Quick setup with Docker

This post describes how I set up Shadowsocks when I travel to visit family in northern capital. Others may find the infodump useful.

Prerequisites

Executables for docker and docker-machine are installed on my laptop. I signed up for a Digital Ocean account and created an API token for it.

These directions presume a unix-like environment: linux, macos, or WSL.

Commands

Using docker-machine I can launch a droplet with Docker already running and configured. Replace token placeholder with your own.

docker-machine create \
  --driver digitalocean \
  --digitalocean-access-token=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
  --digitalocean-region=sgp1 \
  default

That will start a small (5 USD per month) droplet. You will run docker-machine rm default to delete it.

Once the droplet is running I configure the shell to connect to it for Docker commands.

eval $(docker-machine env)

Then build an image. The example below will use shadowsocks-go.

docker build -t local/shadowsocks .

After the image is built, I can run a container from it.

docker run -d -P -e PASSPHRASE=$(dd if=/dev/urandom count=1 bs=30 2>/dev/null | base64) local/shadowsocks

To connect you need several bits of information.

datum source
IP address of droplet docker-machine ls
port number of service docker ps
passphrase docker exec CONTAINER env

Given:

$ docker-machine ls
NAME      ACTIVE   DRIVER         STATE     URL                         SWARM   DOCKER     ERRORS
default   *        digitalocean   Running   tcp://128.199.206.299:2376           v18.09.0   

$ docker ps
CONTAINER ID        IMAGE              COMMAND                  CREATED             STATUS              PORTS                     NAMES
92c4be93b67f        local/shadowsocks  "/bin/sh -c '/usr/sb…"   57 seconds ago      Up 53 seconds       0.0.0.0:32768->5555/tcp   elastic_ellis

$ docker exec -it 92c4be93b67f env | grep PASSPHRASE
PASSPHRASE=PSGXFjFgvBlwe7xzO3BSmSg/a9YcnMXlUyTazyLq

Run:

$ ss-local -s 128.199.206.299 -p 32768 -m aes-128-cfb -k PSGXFjFgvBlwe7xzO3BSmSg/a9YcnMXlUyTazyLq -l 8888

Dockerfile

The docker commands will require one. I give you mine:

FROM golang:latest AS build
  RUN go get -tags netgo github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server

FROM busybox
  ENV ENCRYPTION=aes-128-cfb
  EXPOSE 5555/tcp
  USER nobody:nogroup
  COPY --from=build /go/bin/shadowsocks-server /usr/sbin
  CMD /usr/sbin/shadowsocks-server -p 5555 -m $ENCRYPTION -k $PASSPHRASE

Notice that the passphrase and the encryption method are configurable when the container is started. Notice also that the passphrase is visible in the command – do not run the container where others can run ps and see it.

Summary

  1. launch droplet
  2. build Docker image
  3. start Docker container
  4. find IP+port+passphrase
  5. connect ss-local
  6. destroy when complete