Focuses on a Dockerized Shadowsocks server as well as giving an easy to use Go API to run a Shadowsocks server.
❓ Question, suggestion, request? ➡️ Create an issue!
The Docker image is:
- Based on Scratch (no OS) for a total size of 6MB
- Compatible with all the CPU architectures supported by Docker:
linux/amd64
,linux/386
,linux/arm64
,linux/arm/v6
,linux/arm/v7
,linux/s390x
,linux/ppc64le
andlinux/riscv64
- Shadowsocks is implemented in Go and compiled statically using Go 1.22
Run the container interactively to try it out
docker run -it --rm -p 8388:8388/tcp -p 8388:8388/udp -e PASSWORD=password qmcgaw/ss-server
Or use docker-compose.yml with docker-compose up -d
version: "3.7"
services:
shadowsocks:
image: qmcgaw/ss-server
container_name: shadowsocks
network_mode: bridge
ports:
- 8388:8388/tcp
- 8388:8388/udp
environment:
- PASSWORD=password
- TZ=
restart: always
The environment variables are:
Name | Default | Possible values | Description |
---|---|---|---|
PASSWORD |
Any password | Your password | |
LISTENING_ADDRESS |
:8388 |
Listening address | Internal listening address |
LOG_LEVEL |
INFO |
INFO , ERROR , DEBUG |
Log level |
CIPHER |
chacha20-ietf-poly1305 |
chacha20-ietf-poly1305 , aes-128-gcm , aes-256-gcm |
Cipher to use |
TZ |
Timezone, i.e. America/Montreal |
Timezone for log times display | |
PROFILING |
off |
on or off |
Enable the Go pprof http server on :6060 |
This repository was designed such that it is easy to integrate and launch safely a Shadowsocks server from an existing Go program.
package main
import (
"context"
"fmt"
"os"
"github.com/qdm12/ss-server/pkg/tcpudp"
)
func main() {
logger := &logger{}
password := "password"
address := ":8388"
settings := tcpudp.Settings{
Address: &address,
CipherName: "aes-256-gcm",
Password: &password,
}
server, err := tcpudp.NewServer(settings, logger)
if err != nil {
logger.Error(err.Error())
os.Exit(1)
}
ctx := context.Background()
err = server.Listen(ctx) // blocking call, can be run in a goroutine
if err != nil {
logger.Error(err.Error())
}
}
type logger struct{}
func (l *logger) Debug(s string) { fmt.Println("debug:", s) }
func (l *logger) Info(s string) { fmt.Println("info:", s) }
func (l *logger) Error(s string) { fmt.Println("error:", s) }
The call to server.Listen(ctx, ":8388")
is blocking but you can run in a goroutine and cancel the context ctx
when you want to stop the server.
API for the TCP only and UDP only are almost the same, with the difference that they return an error on exit.
Have also a look at the cmd/ss-server/main.go which is quite straight forward to understand but uses a bit more complex asynchronous parts.
- SIP003 plugins
- Support hex raw keys instead of passwords
- Prometheus stats
- Docker healthcheck + healthcheck endpoint (i.e. for K8s)