Shadowsocks Configuration Format
Shadowsocks takes JSON format configurations:
- server : your hostname or server IP (IPv4/IPv6).
- server_port: server port number.
- local_port: local port number.
- password: a password used to encrypt transfer.
- method: encryption method.
We configure our servers and recommend that you use the chacha20-ietf-poly1305 AEAD cipher because it is the strongest method of encryption.
If configuring your own shadowsocks server, you can choose from either “chacha20-ietf-poly1305” or “aes-256-gcm”.
URI & QR Code
Shadowsocks for Android / IOS also takes BASE64 encoded URI format configs:
The plain URI should be: ss://method:password@hostname:port
The above URI doesn’t follow RFC3986. The password in this case should be plain text, not percent-encoded.
Example: We are using a server at 192.168.100.1:8888 using bf-cfb encryption method and password test/!@#:.
Then, with the plain URI ss://bf-cfb:test/!@#:@192.168.100.1:8888, we can generate the BASE64 encoded URI:
> console.log( “ss://” + btoa(“bf-cfb:test/!@#:@192.168.100.1:8888”) )
To help organize and identify these URIs, you can append a tag after the BASE64 encoded string:
Shadowsocks uses the addresses found in the SOCKS5 address format:
[1-byte type][variable-length host][2-byte port]
Here are the address types defined:
- 0x01 : host is a 4-byte IPv4 address.
- 0x03 : host is a variable length string, starting with a 1-byte length, followed by a max 255-byte domain name.
- 0x04 : host is a 16-byte IPv6 address.
The port number is a 2-byte big-endian unsigned integer.
The ss-local client initiates a connection to ss-remote by sending encrypted data starting with the target address followed by the payload data. The encryption will be different depending on the cipher used.
The ss-remote receives the encrypted data, then decrypts and parses the target address. Then it creates a new TCP connection to the target and forwards the payload data to it. ss-remote receives a reply from the target then encrypts the data and forwards it back to ss-local until it is disconnected.
For obfuscation purposes, local and remote should send the handshake data with some payload in the first packet.
ss-local sends the encrypted data packet containing the target address and payload to ss-remote.
Once the encrypted packet is received, ss-remote decrypts and parses the target address. It then sends a new data packet with the payload to the target. ss-remote receives the data packets from the target and prepends the target address to the payload in each packet. Encrypted copies are sent back to ss-local.
This process can be boiled down to ss-remote performing a network address translation for ss-local.