Full Code of teddysun/shadowsocks_install for AI

master 333637c337f3 cached
67 files
181.8 KB
57.6k tokens
1 requests
Download .txt
Repository: teddysun/shadowsocks_install
Branch: master
Commit: 333637c337f3
Files: 67
Total size: 181.8 KB

Directory structure:
gitextract_yj3jp4x6/

├── Readme.md
├── docker/
│   ├── go-shadowsocks2/
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   ├── build_go-shadowsocks2.sh
│   │   ├── go-shadowsocks2.sh
│   │   ├── v2ray-plugin.sh
│   │   └── xray-plugin.sh
│   ├── shadowsocks-go/
│   │   ├── .dockerignore
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   ├── config_sample.json
│   │   └── shadowsocks-go.sh
│   ├── shadowsocks-libev/
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── Dockerfile_edge.architecture
│   │   ├── README.md
│   │   ├── build_v2ray-plugin.sh
│   │   ├── build_xray-plugin.sh
│   │   ├── config_sample.json
│   │   ├── v2ray-plugin.sh
│   │   └── xray-plugin.sh
│   ├── shadowsocks-python/
│   │   ├── .dockerignore
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   └── config_sample.json
│   ├── shadowsocks-r/
│   │   ├── .dockerignore
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   └── config_sample.json
│   └── shadowsocks-rust/
│       ├── Dockerfile
│       ├── Dockerfile.alpine
│       ├── Dockerfile.architecture
│       ├── Dockerfile.debian
│       ├── Dockerfile_edge.alpine
│       ├── README.md
│       ├── build_v2ray-plugin.sh
│       ├── build_xray-plugin.sh
│       ├── config_sample.json
│       ├── shadowsocks-rust-alpine.sh
│       ├── shadowsocks-rust-debian.sh
│       ├── v2ray-plugin.sh
│       └── xray-plugin.sh
├── haproxy.sh
├── sample_config/
│   ├── shadowsocks-go/
│   │   └── config.json
│   ├── shadowsocks-libev/
│   │   └── config.json
│   ├── shadowsocks-manager/
│   │   └── config.json
│   ├── shadowsocks-python/
│   │   └── config.json
│   └── shadowsocks-r/
│       └── config.json
├── shadowsocks
├── shadowsocks-all.sh
├── shadowsocks-crond.sh
├── shadowsocks-debian
├── shadowsocks-go
├── shadowsocks-go-debian
├── shadowsocks-go.sh
├── shadowsocks-libev
├── shadowsocks-libev-debian
├── shadowsocks-libev-debian.sh
├── shadowsocks-libev.sh
├── shadowsocks-manager
├── shadowsocks.sh
├── shadowsocksR
├── shadowsocksR-debian
└── shadowsocksR.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: Readme.md
================================================
![Shadowsocks](https://github.com/teddysun/shadowsocks_install/raw/master/shadowsocks.png)
# Auto install Shadowsocks Server

shadowsocks.sh
===============
- Auto Install Shadowsocks(Python) Server for CentOS/Debian/Ubuntu
- https://teddysun.com/342.html

shadowsocks-libev.sh
===============
- Auto Install Shadowsocks(libev) Server for CentOS
- https://teddysun.com/357.html

shadowsocks-libev-debian.sh
===============
- Auto Install Shadowsocks(libev) Server for Debian/Ubuntu
- https://teddysun.com/358.html

shadowsocks-go.sh
===============
- Auto Install Shadowsocks(Go) Server for CentOS/Debian/Ubuntu
- https://teddysun.com/392.html

shadowsocks-crond.sh
===============
- Check Shadowsocks(All version) Server is running or not, and start it if not running
- https://teddysun.com/525.html

shadowsocksR.sh
===============
- Auto Install ShadowsocksR Server for CentOS/Debian/Ubuntu
- https://shadowsocks.be/9.html

shadowsocks-all.sh
==================
- Auto Install Shadowsocks Server (all version) for CentOS/Debian/Ubuntu
- https://teddysun.com/486.html

haproxy.sh
===============
- Auto Install haproxy for Shadowsocks Server
- https://shadowsocks.be/10.html

Copyright (C) 2014-2019 Teddysun


================================================
FILE: docker/go-shadowsocks2/Dockerfile.architecture
================================================
# Dockerfile for go-shadowsocks2 based alpine
# Copyright (C) 2019 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/go-shadowsocks2
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:latest
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY go-shadowsocks2.sh /root/go-shadowsocks2.sh
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
RUN set -ex \
	&& apk add --no-cache tzdata \
	&& chmod +x /root/go-shadowsocks2.sh /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/go-shadowsocks2.sh "${TARGETPLATFORM}" \
	&& /root/v2ray-plugin.sh "${TARGETPLATFORM}" \
	&& /root/xray-plugin.sh "${TARGETPLATFORM}" \
	&& rm -fv /root/go-shadowsocks2.sh /root/v2ray-plugin.sh /root/xray-plugin.sh

ENV TZ=Asia/Shanghai
ENV SERVER_PORT=9000
ENV METHOD=AEAD_CHACHA20_POLY1305
ENV PASSWORD=teddysun.com
ENV ARGS=
CMD exec go-shadowsocks2 \
	-s "ss://${METHOD}:${PASSWORD}@:${SERVER_PORT}" \
	-verbose \
	${ARGS}

================================================
FILE: docker/go-shadowsocks2/README.md
================================================
## Go-shadowsocks2 Docker Image by Teddysun

[go-shadowsocks2][1] is a fresh implementation of Shadowsocks in Go which can help you get through firewalls.

Based on alpine with latest version [go-shadowsocks2][1] and [v2ray-plugin][6] + [xray-plugin][7].

Docker images are built for quick deployment in various computing cloud providers.

For more information on docker and containerization technologies, refer to [official document][3].

## Prepare the host

If you need to install docker by yourself, follow the [official installation guide][4].

## Pull the image

```bash
$ docker pull teddysun/go-shadowsocks2
```

This pulls the latest release of go-shadowsocks2.

It can be found at [Docker Hub][5].

## Start a container

You **must set environment variable** at first.

- `SERVER_PORT`: Server listening on port, default  `9000`;
- `METHOD`: Encryption method to use, available ciphers: `AEAD_AES_128_GCM`, `AEAD_AES_256_GCM`, `AEAD_CHACHA20_POLY1305`, default `AEAD_CHACHA20_POLY1305`;
- `PASSWORD`: Your own password, default `teddysun.com`;
- `ARGS`: Additional arguments, for example: `-plugin v2ray-plugin -plugin-opts "server"` or `-plugin xray-plugin -plugin-opts "server"`. 

For more `v2ray-plugin` configrations please visit v2ray-plugin [usage][8].

For more `xray-plugin` configrations please visit xray-plugin [usage][9].

**1.** There is an example to start a container with default environment variables:

```bash
$ docker run -d -p 9000:9000 -p 9000:9000/udp --name go-ss --restart=always teddysun/go-shadowsocks2
```

**2.** There is an example to start a container that listen on port `8989`, using `AEAD_AES_256_GCM` AEAD cipher with password `password00`:

```bash
$ docker run -d -p 8989:8989 -p 8989:8989/udp --name go-ss --restart=always -e SERVER_PORT=8989 -e METHOD=AEAD_AES_256_GCM -e PASSWORD=password00 teddysun/go-shadowsocks2
```

**3.** There is an example to start a container that listen on port `8989`, using `AEAD_AES_256_GCM` AEAD cipher with password `password00` and supported SIP003 plugins `v2ray-plugin` over websocket (HTTP):

```bash
$ docker run -d -p 8989:8989 -p 8989:8989/udp --name go-ss --restart=always -e SERVER_PORT=8989 -e METHOD=AEAD_AES_256_GCM -e PASSWORD=password00 -e ARGS="-plugin v2ray-plugin -plugin-opts "server"" teddysun/go-shadowsocks2
```

**4.** There is an example to start a container that listen on port `8989`, using `AEAD_AES_256_GCM` AEAD cipher with password `password00` and supported SIP003 plugins `xray-plugin` over websocket (HTTP):

```bash
$ docker run -d -p 8989:8989 -p 8989:8989/udp --name go-ss --restart=always -e SERVER_PORT=8989 -e METHOD=AEAD_AES_256_GCM -e PASSWORD=password00 -e ARGS="-plugin xray-plugin -plugin-opts "server"" teddysun/go-shadowsocks2
```

**Warning**: The port number must be opened in firewall.

[1]: https://github.com/shadowsocks/go-shadowsocks2
[2]: https://shadowsocks.org/en/index.html
[3]: https://docs.docker.com/
[4]: https://docs.docker.com/install/
[5]: https://hub.docker.com/r/teddysun/go-shadowsocks2/
[6]: https://github.com/teddysun/v2ray-plugin
[7]: https://github.com/teddysun/xray-plugin
[8]: https://github.com/teddysun/v2ray-plugin#usage
[9]: https://github.com/teddysun/xray-plugin#usage

================================================
FILE: docker/go-shadowsocks2/build_go-shadowsocks2.sh
================================================
#!/bin/sh
#
# This is a Shell script for build multi-architectures go-shadowsocks2 binary file
# 
# Supported architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x
# 
# Copyright (C) 2020 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/go-shadowsocks2

cur_dir="$(pwd)"

COMMANDS=( git go )
for CMD in "${COMMANDS[@]}"; do
    if [ ! "$(command -v "${CMD}")" ]; then
        echo "${CMD} is not installed, please install it and try again" && exit 1
    fi
done

cd ${cur_dir}
git clone https://github.com/shadowsocks/go-shadowsocks2.git
cd go-shadowsocks2 || exit 2
go get -d -v

LDFLAGS="-s -w"
ARCHS=( 386 amd64 arm arm64 ppc64le s390x )
ARMS=( 6 7 )

for ARCH in ${ARCHS[@]}; do
    if [ "${ARCH}" = "arm" ]; then
        for V in ${ARMS[@]}; do
            echo "Building go-shadowsocks2_linux_${ARCH}${V}"
            env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} GOARM=${V} go build -v -ldflags "${LDFLAGS}" -o ${cur_dir}/go-shadowsocks2_linux_${ARCH}${V}
        done
    else
        echo "Building go-shadowsocks2_linux_${ARCH}"
        env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -v -ldflags "${LDFLAGS}" -o ${cur_dir}/go-shadowsocks2_linux_${ARCH}
    fi
done

chmod +x ${cur_dir}/go-shadowsocks2_linux_*
# clean up
cd ${cur_dir} && rm -fr go-shadowsocks2


================================================
FILE: docker/go-shadowsocks2/go-shadowsocks2.sh
================================================
#!/bin/sh
#
# This is a Shell script for go-shadowsocks2 based alpine with Docker image
# 
# Copyright (C) 2019 - 2020 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/go-shadowsocks2

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download binary file
GO_SHADOWSOCKS2_FILE="go-shadowsocks2_linux_${ARCH}"
echo "Downloading go-shadowsocks2 binary file: ${GO_SHADOWSOCKS2_FILE}"
wget -O /usr/bin/go-shadowsocks2 https://dl.lamp.sh/files/${GO_SHADOWSOCKS2_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download go-shadowsocks2 binary file: ${GO_SHADOWSOCKS2_FILE}" && exit 1
fi
chmod +x /usr/bin/go-shadowsocks2
echo "Download go-shadowsocks2 binary file: ${GO_SHADOWSOCKS2_FILE} completed"


================================================
FILE: docker/go-shadowsocks2/v2ray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for go-shadowsocks2 supported SIP003 plugins based alpine with Docker image
# 
# Copyright (C) 2019 - 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download v2ray-plugin binary file
V2RAY_PLUGIN_FILE="v2ray-plugin_linux_${ARCH}"
echo "Downloading v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE}"
wget -O /usr/bin/v2ray-plugin https://dl.lamp.sh/files/${V2RAY_PLUGIN_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE}" && exit 1
fi
chmod +x /usr/bin/v2ray-plugin
echo "Download v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE} completed"


================================================
FILE: docker/go-shadowsocks2/xray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for go-shadowsocks2 supported SIP003 plugins based alpine with Docker image
# 
# Copyright (C) 2019 - 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/teddysun/xray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download xray-plugin binary file
XRAY_PLUGIN_FILE="xray-plugin_linux_${ARCH}"
echo "Downloading xray-plugin binary file: ${XRAY_PLUGIN_FILE}"
wget -O /usr/bin/xray-plugin https://dl.lamp.sh/files/${XRAY_PLUGIN_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download xray-plugin binary file: ${XRAY_PLUGIN_FILE}" && exit 1
fi
chmod +x /usr/bin/xray-plugin
echo "Download xray-plugin binary file: ${XRAY_PLUGIN_FILE} completed"


================================================
FILE: docker/shadowsocks-go/.dockerignore
================================================
.dockerignore
README.md

================================================
FILE: docker/shadowsocks-go/Dockerfile
================================================
# Dockerfile for Shadowsocks-go based alpine
# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-go

FROM alpine:latest
LABEL maintainer="Teddysun <i@teddysun.com>"

WORKDIR /root
COPY shadowsocks-go.sh /root/shadowsocks-go.sh
COPY config_sample.json /etc/shadowsocks-go/config.json
RUN set -ex \
	&& apk add --no-cache tzdata \
	&& chmod +x /root/shadowsocks-go.sh \
	&& /root/shadowsocks-go.sh \
	&& rm -fv /root/shadowsocks-go.sh

ENV TZ=Asia/Shanghai
VOLUME /etc/shadowsocks-go

CMD [ "shadowsocks-server", "-c", "/etc/shadowsocks-go/config.json" ]


================================================
FILE: docker/shadowsocks-go/Dockerfile.architecture
================================================
# Dockerfile for Shadowsocks-go based alpine
# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-go

FROM alpine:latest
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY shadowsocks-go.sh /root/shadowsocks-go.sh
COPY config_sample.json /etc/shadowsocks-go/config.json
RUN set -ex \
	&& apk add --no-cache tzdata \
	&& chmod +x /root/shadowsocks-go.sh \
	&& /root/shadowsocks-go.sh "${TARGETPLATFORM}" \
	&& rm -fv /root/shadowsocks-go.sh

ENV TZ=Asia/Shanghai
VOLUME /etc/shadowsocks-go

CMD [ "shadowsocks-server", "-c", "/etc/shadowsocks-go/config.json" ]


================================================
FILE: docker/shadowsocks-go/README.md
================================================
## Shadowsocks-go Docker Image by Teddysun

[Shadowsocks-go][1] is a lightweight tunnel proxy which can help you get through firewalls.

It is a port of [Shadowsocks][2] created by @cyfdecyf.

Docker images are built for quick deployment in various computing cloud providers.

For more information on docker and containerization technologies, refer to [official document][3].

## Prepare the host

If you need to install docker by yourself, follow the [official installation guide][4].

## Pull the image

```bash
$ docker pull teddysun/shadowsocks-go
```

This pulls the latest release of shadowsocks-go.

It can be found at [Docker Hub][5].

## Start a container

You **must create a configuration file**  `/etc/shadowsocks-go/config.json` in host at first:

```
$ mkdir -p /etc/shadowsocks-go
```

A sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "local_port":1080,
    "password":"password0",
    "method":"aes-256-cfb",
    "timeout":120
}
```

This container with sample configuration `/etc/shadowsocks-go/config.json`

There is an example to start a container that listens on `9000` (both TCP and UDP):

```bash
$ docker run -d -p 9000:9000 -p 9000:9000/udp --name ss-go --restart=always -v /etc/shadowsocks-go:/etc/shadowsocks-go teddysun/shadowsocks-go
```

**Warning**: The port number must be same as configuration and opened in firewall.

[1]: https://github.com/shadowsocks/shadowsocks-go
[2]: https://shadowsocks.org/en/index.html
[3]: https://docs.docker.com/
[4]: https://docs.docker.com/install/
[5]: https://hub.docker.com/r/teddysun/shadowsocks-go/

================================================
FILE: docker/shadowsocks-go/config_sample.json
================================================
{
    "server":"0.0.0.0",
    "server_port":9000,
    "local_port":1080,
    "password":"password0",
    "method":"aes-256-cfb",
    "timeout":120
}

================================================
FILE: docker/shadowsocks-go/shadowsocks-go.sh
================================================
#!/bin/sh
#
# This is a Shell script for shadowsocks-go based alpine with Docker image
# 
# Copyright (C) 2019 - 2020 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-go

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download binary file
SHADOWSOCKS_GO_FILE="shadowsocks-go_linux_${ARCH}"
echo "Downloading shadowsocks-go binary file: ${SHADOWSOCKS_GO_FILE}"
wget -O /usr/bin/shadowsocks-server https://dl.lamp.sh/files/${SHADOWSOCKS_GO_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download shadowsocks-go binary file: ${SHADOWSOCKS_GO_FILE}" && exit 1
fi
chmod +x /usr/bin/shadowsocks-server
echo "Download shadowsocks-go binary file: ${SHADOWSOCKS_GO_FILE} completed"


================================================
FILE: docker/shadowsocks-libev/Dockerfile
================================================
# Dockerfile for shadowsocks-libev based alpine
# Copyright (C) 2018 - 2026 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-libev
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:3.23
LABEL maintainer="Teddysun <i@teddysun.com>"

WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY config_sample.json /etc/shadowsocks-libev/config.json
RUN set -ex \
	&& runDeps="git build-base c-ares-dev cmake libcap libev-dev libtool libsodium-dev linux-headers mbedtls-dev pcre2-dev" \
	&& apk add --no-cache --virtual .build-deps ${runDeps} \
	&& mkdir -p /root/libev \
	&& cd /root/libev \
	&& git clone --depth=1 https://github.com/shadowsocks/shadowsocks-libev.git . \
	&& git submodule update --init --recursive \
	&& mkdir -p build \
	&& cd build \
	&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTING=OFF -DWITH_STATIC=OFF -DCMAKE_BUILD_TYPE=Release \
	&& make -j$(getconf _NPROCESSORS_ONLN) \
	&& make install \
	&& ls /usr/bin/ss-* | xargs -n1 setcap cap_net_bind_service+ep \
	&& apk add --no-cache \
		tzdata \
		rng-tools \
		ca-certificates \
		$(scanelf --needed --nobanner /usr/bin/ss-* \
		| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
		| xargs -r apk info --installed \
		| sort -u) \
	&& apk del .build-deps \
	&& cd /root \
	&& rm -rf /root/libev \
	&& chmod +x /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/v2ray-plugin.sh \
	&& /root/xray-plugin.sh \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh

VOLUME /etc/shadowsocks-libev
ENV TZ=Asia/Shanghai
CMD [ "ss-server", "-c", "/etc/shadowsocks-libev/config.json" ]


================================================
FILE: docker/shadowsocks-libev/Dockerfile.architecture
================================================
# Dockerfile for shadowsocks-libev based alpine
# Copyright (C) 2018 - 2026 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-libev
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:3.23
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY config_sample.json /etc/shadowsocks-libev/config.json
RUN set -ex \
	&& runDeps="git build-base c-ares-dev cmake libcap libev-dev libtool libsodium-dev linux-headers mbedtls-dev pcre2-dev" \
	&& apk add --no-cache --virtual .build-deps ${runDeps} \
	&& mkdir -p /root/libev \
	&& cd /root/libev \
	&& git clone --depth=1 https://github.com/shadowsocks/shadowsocks-libev.git . \
	&& git submodule update --init --recursive \
	&& mkdir -p build \
	&& cd build \
	&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTING=OFF -DWITH_STATIC=OFF -DCMAKE_BUILD_TYPE=Release \
	&& make -j$(getconf _NPROCESSORS_ONLN) \
	&& make install \
	&& ls /usr/bin/ss-* | xargs -n1 setcap cap_net_bind_service+ep \
	&& apk add --no-cache \
		tzdata \
		rng-tools \
		ca-certificates \
		$(scanelf --needed --nobanner /usr/bin/ss-* \
		| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
		| xargs -r apk info --installed \
		| sort -u) \
	&& apk del .build-deps \
	&& cd /root \
	&& rm -rf /root/libev \
	&& chmod +x /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/v2ray-plugin.sh "${TARGETPLATFORM}" \
	&& /root/xray-plugin.sh "${TARGETPLATFORM}" \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh

VOLUME /etc/shadowsocks-libev
ENV TZ=Asia/Shanghai
CMD [ "ss-server", "-c", "/etc/shadowsocks-libev/config.json" ]


================================================
FILE: docker/shadowsocks-libev/Dockerfile_edge.architecture
================================================
# Dockerfile for shadowsocks-libev based alpine
# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-libev
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:edge
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY config_sample.json /etc/shadowsocks-libev/config.json
RUN set -ex \
	&& echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories \
	&& apk add --no-cache tzdata rng-tools ca-certificates shadowsocks-libev \
	&& chmod +x /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/v2ray-plugin.sh "${TARGETPLATFORM}" \
	&& /root/xray-plugin.sh "${TARGETPLATFORM}" \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh

VOLUME /etc/shadowsocks-libev
ENV TZ=Asia/Shanghai
CMD [ "/usr/bin/ss-server", "-c", "/etc/shadowsocks-libev/config.json" ]


================================================
FILE: docker/shadowsocks-libev/README.md
================================================
## Shadowsocks-libev Docker Image by Teddysun

[shadowsocks-libev][1] is a lightweight secured socks5 proxy for embedded devices and low end boxes.

It is a port of [shadowsocks][2] created by @clowwindy maintained by @madeye and @linusyang.

Based on alpine with latest version [shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev) and [v2ray-plugin](https://github.com/teddysun/v2ray-plugin), [xray-plugin](https://github.com/teddysun/xray-plugin).

Docker images are built for quick deployment in various computing cloud providers.

For more information on docker and containerization technologies, refer to [official document][3].

## Prepare the host

If you need to install docker by yourself, follow the [official installation guide][4].

## Pull the image

```bash
$ docker pull teddysun/shadowsocks-libev
```

This pulls the latest release of shadowsocks-libev.

It can be found at [Docker Hub][5].

## Start a container

You **must create a configuration file**  `/etc/shadowsocks-libev/config.json` in host at first:

```
$ mkdir -p /etc/shadowsocks-libev
```

A sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "fast_open":true,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp"
}
```

If you want to enable **v2ray-plugin**, a sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "fast_open":true,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp",
    "plugin":"v2ray-plugin",
    "plugin_opts":"server"
}
```

If you want to enable **xray-plugin**, a sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "fast_open":true,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp",
    "plugin":"xray-plugin",
    "plugin_opts":"server"
}
```

For more `v2ray-plugin` configrations please visit v2ray-plugin [usage][6].

For more `xray-plugin` configrations please visit xray-plugin [usage][7].

This container with sample configuration `/etc/shadowsocks-libev/config.json`

There is an example to start a container that listens on `9000` (both TCP and UDP):

```bash
$ docker run -d -p 9000:9000 -p 9000:9000/udp --name ss-libev --restart=always -v /etc/shadowsocks-libev:/etc/shadowsocks-libev teddysun/shadowsocks-libev
```

**Warning**: The port number must be same as configuration and opened in firewall.

[1]: https://github.com/shadowsocks/shadowsocks-libev
[2]: https://shadowsocks.org/en/index.html
[3]: https://docs.docker.com/
[4]: https://docs.docker.com/install/
[5]: https://hub.docker.com/r/teddysun/shadowsocks-libev/
[6]: https://github.com/shadowsocks/v2ray-plugin#usage
[7]: https://github.com/teddysun/xray-plugin#usage

================================================
FILE: docker/shadowsocks-libev/build_v2ray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for build multi-architectures v2ray-plugin binary file
# 
# Supported architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x
# 
# Copyright (C) 2020 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/v2ray-plugin

cur_dir="$(pwd)"

COMMANDS=( git go )
for CMD in "${COMMANDS[@]}"; do
    if [ ! "$(command -v "${CMD}")" ]; then
        echo "${CMD} is not installed, please install it and try again" && exit 1
    fi
done

cd ${cur_dir}
git clone https://github.com/shadowsocks/v2ray-plugin.git
cd v2ray-plugin || exit 2

VERSION="$(git describe --tags)"
LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS=""
ARCHS=( 386 amd64 arm arm64 ppc64le s390x )
ARMS=( 6 7 )

for ARCH in ${ARCHS[@]}; do
    if [ "${ARCH}" = "arm" ]; then
        for V in ${ARMS[@]}; do
            echo "Building v2ray-plugin_linux_${ARCH}${V}"
            env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} GOARM=${V} go build -v -ldflags "${LDFLAGS}" -gcflags "${GCFLAGS}" -o ${cur_dir}/v2ray-plugin_linux_${ARCH}${V}
        done
    else
        echo "Building v2ray-plugin_linux_${ARCH}"
        env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -v -ldflags "${LDFLAGS}" -gcflags "${GCFLAGS}" -o ${cur_dir}/v2ray-plugin_linux_${ARCH}
    fi
done

# clean up
cd ${cur_dir} && rm -fr v2ray-plugin


================================================
FILE: docker/shadowsocks-libev/build_xray-plugin.sh
================================================
#!/bin/bash
#
# This is a Shell script for build multi-architectures xray-plugin binary file
# 
# Supported architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x
# 
# Copyright (C) 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/teddysun/xray-plugin

cur_dir="$(pwd)"

COMMANDS=( git go )
for CMD in "${COMMANDS[@]}"; do
    if [ ! "$(command -v "${CMD}")" ]; then
        echo "${CMD} is not installed, please install it and try again" && exit 1
    fi
done

cd ${cur_dir}
git clone https://github.com/teddysun/xray-plugin.git
cd xray-plugin || exit 2

VERSION="$(git describe --tags)"
LDFLAGS="-X main.VERSION=$VERSION -s -w"
ARCHS=( 386 amd64 arm arm64 ppc64le s390x )
ARMS=( 6 7 )

for ARCH in ${ARCHS[@]}; do
    if [ "${ARCH}" = "arm" ]; then
        for V in ${ARMS[@]}; do
            echo "Building xray-plugin_linux_${ARCH}${V}"
            env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} GOARM=${V} go build -v -trimpath -ldflags "${LDFLAGS}" -o ${cur_dir}/xray-plugin_linux_${ARCH}${V}
        done
    else
        echo "Building xray-plugin_linux_${ARCH}"
        env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -v -trimpath -ldflags "${LDFLAGS}" -o ${cur_dir}/xray-plugin_linux_${ARCH}
    fi
done

# clean up
cd ${cur_dir} && rm -fr xray-plugin


================================================
FILE: docker/shadowsocks-libev/config_sample.json
================================================
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "fast_open":true,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp"
}

================================================
FILE: docker/shadowsocks-libev/v2ray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for shadowsocks-libev based alpine with Docker image
# 
# Copyright (C) 2019 - 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-libev
# https://github.com/shadowsocks/simple-obfs
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download v2ray-plugin binary file
V2RAY_PLUGIN_FILE="v2ray-plugin_linux_${ARCH}"
echo "Downloading v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE}"
wget -O /usr/bin/v2ray-plugin https://dl.lamp.sh/files/${V2RAY_PLUGIN_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE}" && exit 1
fi
chmod +x /usr/bin/v2ray-plugin
echo "Download v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE} completed"


================================================
FILE: docker/shadowsocks-libev/xray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for shadowsocks-libev supported SIP003 plugins based alpine with Docker image
# 
# Copyright (C) 2019 - 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/teddysun/xray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download xray-plugin binary file
XRAY_PLUGIN_FILE="xray-plugin_linux_${ARCH}"
echo "Downloading xray-plugin binary file: ${XRAY_PLUGIN_FILE}"
wget -O /usr/bin/xray-plugin https://dl.lamp.sh/files/${XRAY_PLUGIN_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download xray-plugin binary file: ${XRAY_PLUGIN_FILE}" && exit 1
fi
chmod +x /usr/bin/xray-plugin
echo "Download xray-plugin binary file: ${XRAY_PLUGIN_FILE} completed"


================================================
FILE: docker/shadowsocks-python/.dockerignore
================================================
.dockerignore
README.md

================================================
FILE: docker/shadowsocks-python/Dockerfile
================================================
# Dockerfile for Shadowsocks-Python based alpine
# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks/tree/master

FROM python:3.9-alpine
LABEL maintainer="Teddysun <i@teddysun.com>"

RUN set -ex \
	&& apk add --no-cache unzip libsodium-dev openssl mbedtls \
	&& cd /tmp \
	&& wget -O shadowsocks.zip https://github.com/shadowsocks/shadowsocks/archive/master.zip \
	&& unzip shadowsocks.zip \
	&& cd shadowsocks-master \
	&& python setup.py install \
	&& cd /tmp \
	&& rm -fr shadowsocks.zip shadowsocks-master 

COPY config_sample.json /etc/shadowsocks-python/config.json
VOLUME /etc/shadowsocks-python

CMD [ "ssserver", "-c", "/etc/shadowsocks-python/config.json" ]


================================================
FILE: docker/shadowsocks-python/Dockerfile.architecture
================================================
# Dockerfile for Shadowsocks-Python based alpine
# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks/tree/master

FROM python:3.9-alpine
LABEL maintainer="Teddysun <i@teddysun.com>"

RUN set -ex \
	&& apk add --no-cache unzip libsodium-dev openssl mbedtls \
	&& cd /tmp \
	&& wget -O shadowsocks.zip https://github.com/shadowsocks/shadowsocks/archive/master.zip \
	&& unzip shadowsocks.zip \
	&& cd shadowsocks-master \
	&& python setup.py install \
	&& cd /tmp \
	&& rm -fr shadowsocks.zip shadowsocks-master 

COPY config_sample.json /etc/shadowsocks-python/config.json
VOLUME /etc/shadowsocks-python

CMD [ "ssserver", "-c", "/etc/shadowsocks-python/config.json" ]


================================================
FILE: docker/shadowsocks-python/README.md
================================================
## Shadowsocks-Python Docker Image by Teddysun

[Shadowsocks][1] is a lightweight secured socks5 proxy for embedded devices and low end boxes.

It is a port of [Shadowsocks][2] created by @clowwindy .

Docker images are built for quick deployment in various computing cloud providers.

For more information on docker and containerization technologies, refer to [official document][3].

## Prepare the host

If you need to install docker by yourself, follow the [official installation guide][4].

## Pull the image

```bash
$ docker pull teddysun/shadowsocks-python
```

This pulls the latest release of shadowsocks-python.

It can be found at [Docker Hub][5].

## Start a container

You **must create a configuration file**  `/etc/shadowsocks-python/config.json` in host at first:

```
$ mkdir -p /etc/shadowsocks-python
```

A sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "local_address":"127.0.0.1",
    "local_port":1080,
    "password":"password0",
    "timeout":120,
    "method":"aes-256-cfb",
    "fast_open":true
}
```

This container with sample configuration `/etc/shadowsocks-python/config.json`

There is an example to start a container that listens on `9000` (both TCP and UDP):

```bash
$ docker run -d -p 9000:9000 -p 9000:9000/udp --name ss --restart=always -v /etc/shadowsocks-python:/etc/shadowsocks-python teddysun/shadowsocks-python
```

**Warning**: The port number must be same as configuration and opened in firewall.

[1]: https://github.com/shadowsocks/shadowsocks/tree/master
[2]: https://shadowsocks.org/en/index.html
[3]: https://docs.docker.com/
[4]: https://docs.docker.com/install/
[5]: https://hub.docker.com/r/teddysun/shadowsocks-python/

================================================
FILE: docker/shadowsocks-python/config_sample.json
================================================
{
    "server":"0.0.0.0",
    "server_port":9000,
    "local_address":"127.0.0.1",
    "local_port":1080,
    "password":"password0",
    "timeout":120,
    "method":"aes-256-cfb",
    "fast_open":true
}

================================================
FILE: docker/shadowsocks-r/.dockerignore
================================================
.dockerignore
README.md

================================================
FILE: docker/shadowsocks-r/Dockerfile
================================================
# Dockerfile for ShadowsocksR based alpine
# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocksrr/shadowsocksr

FROM python:3.9-alpine
LABEL maintainer="Teddysun <i@teddysun.com>"

RUN set -ex \
	&& apk add --no-cache tar libsodium-dev openssl \
	&& wget -O /tmp/shadowsocksr-3.2.2.tar.gz https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz \
	&& tar zxf /tmp/shadowsocksr-3.2.2.tar.gz -C /tmp \
	&& mv /tmp/shadowsocksr-3.2.2/shadowsocks /usr/local/ \
	&& rm -fr /tmp/shadowsocksr-3.2.2 \
	&& rm -f /tmp/shadowsocksr-3.2.2.tar.gz

COPY ./config_sample.json /etc/shadowsocks-r/config.json
VOLUME /etc/shadowsocks-r

CMD [ "/usr/local/shadowsocks/server.py", "-c", "/etc/shadowsocks-r/config.json" ]


================================================
FILE: docker/shadowsocks-r/Dockerfile.architecture
================================================
# Dockerfile for ShadowsocksR based alpine
# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocksrr/shadowsocksr

FROM python:3.9-alpine
LABEL maintainer="Teddysun <i@teddysun.com>"

RUN set -ex \
	&& apk add --no-cache tar libsodium-dev openssl \
	&& wget -O /tmp/shadowsocksr-3.2.2.tar.gz https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz \
	&& tar zxf /tmp/shadowsocksr-3.2.2.tar.gz -C /tmp \
	&& mv /tmp/shadowsocksr-3.2.2/shadowsocks /usr/local/ \
	&& rm -fr /tmp/shadowsocksr-3.2.2 \
	&& rm -f /tmp/shadowsocksr-3.2.2.tar.gz

COPY ./config_sample.json /etc/shadowsocks-r/config.json
VOLUME /etc/shadowsocks-r

CMD [ "/usr/local/shadowsocks/server.py", "-c", "/etc/shadowsocks-r/config.json" ]


================================================
FILE: docker/shadowsocks-r/README.md
================================================
## ShadowsocksR Docker Image by Teddysun

[shadowsocksr][1] is a lightweight secured socks5 proxy for embedded devices and low end boxes.

It is a port of [shadowsocks][2] created by @clowwindy maintained by @breakwa11 and @Akkariiin.

Docker images are built for quick deployment in various computing cloud providers.

For more information on docker and containerization technologies, refer to [official document][3].

## Prepare the host

If you need to install docker by yourself, follow the [official installation guide][4].

## Pull the image

```bash
$ docker pull teddysun/shadowsocks-r
```

This pulls the latest release of shadowsocks-r.

It can be found at [Docker Hub][5].

## Start a container

You **must create a configuration file**  `/etc/shadowsocks-r/config.json` in host at first:

```
$ mkdir -p /etc/shadowsocks-r
```

A sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_ipv6":"::",
    "server_port":9000,
    "local_address":"127.0.0.1",
    "local_port":1080,
    "password":"password0",
    "timeout":120,
    "method":"aes-256-cfb",
    "protocol":"origin",
    "protocol_param":"",
    "obfs":"plain",
    "obfs_param":"",
    "redirect":"",
    "dns_ipv6":false,
    "fast_open":true,
    "workers":1
}
```

This container with sample configuration `/etc/shadowsocks-r/config.json`

There is an example to start a container that listens on `9000` (both TCP and UDP):

```bash
$ docker run -d -p 9000:9000 -p 9000:9000/udp --name ssr --restart=always -v /etc/shadowsocks-r:/etc/shadowsocks-r teddysun/shadowsocks-r
```

**Warning**: The port number must be same as configuration and opened in firewall.

[1]: https://github.com/shadowsocksrr/shadowsocksr
[2]: https://shadowsocks.org/en/index.html
[3]: https://docs.docker.com/
[4]: https://docs.docker.com/install/
[5]: https://hub.docker.com/r/teddysun/shadowsocks-r/

================================================
FILE: docker/shadowsocks-r/config_sample.json
================================================
{
    "server":"0.0.0.0",
    "server_ipv6":"::",
    "server_port":9000,
    "local_address":"127.0.0.1",
    "local_port":1080,
    "password":"password0",
    "timeout":120,
    "method":"aes-256-cfb",
    "protocol":"origin",
    "protocol_param":"",
    "obfs":"plain",
    "obfs_param":"",
    "redirect":"",
    "dns_ipv6":false,
    "fast_open":true,
    "workers":1
}

================================================
FILE: docker/shadowsocks-rust/Dockerfile
================================================
# Dockerfile for shadowsocks-rust based alpine
# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:latest

WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY config_sample.json /etc/shadowsocks-rust/config.json
RUN set -ex \
	&& runDeps="git build-base c-ares-dev autoconf automake libev-dev libtool libsodium-dev linux-headers mbedtls-dev pcre-dev openssl-dev cargo" \
	&& apk add --no-cache --virtual .build-deps ${runDeps} \
	&& mkdir -p /root/rust \
	&& cd /root/rust \
	&& VERSION=$(wget --no-check-certificate -qO- https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest | grep 'tag_name' | cut -d\" -f4) \
	&& git clone -b ${VERSION} --depth=1 https://github.com/shadowsocks/shadowsocks-rust.git . \
	&& cargo build --release --features "local-tun local-redir stream-cipher aead-cipher-2022" --verbose \
	&& cp -pv target/release/sslocal /usr/bin \
	&& cp -pv target/release/ssmanager /usr/bin \
	&& cp -pv target/release/ssserver /usr/bin \
	&& cp -pv target/release/ssservice /usr/bin \
	&& cp -pv target/release/ssurl /usr/bin \
	&& apk add --no-cache \
		tzdata \
		rng-tools \
		ca-certificates \
		libgcc \
		$(scanelf --needed --nobanner /usr/bin/ss* \
		| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
		| xargs -r apk info --installed \
		| sort -u) \
	&& apk del .build-deps \
	&& cd /root \
	&& rm -rf /root/rust \
	&& chmod +x /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/v2ray-plugin.sh \
	&& /root/xray-plugin.sh \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh

VOLUME /etc/shadowsocks-rust
ENV TZ=Asia/Shanghai
CMD [ "/usr/bin/ssservice", "server", "--log-without-time", "-c", "/etc/shadowsocks-rust/config.json" ]


================================================
FILE: docker/shadowsocks-rust/Dockerfile.alpine
================================================
# Dockerfile for shadowsocks-rust based alpine
# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:latest
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY shadowsocks-rust-alpine.sh /root/shadowsocks-rust-alpine.sh
COPY config_sample.json /etc/shadowsocks-rust/config.json
RUN set -ex \
	&& chmod +x /root/shadowsocks-rust-alpine.sh /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/shadowsocks-rust-alpine.sh "${TARGETPLATFORM}" \
	&& rm -f /root/shadowsocks-rust-alpine.sh \
	&& apk add --no-cache \
		tzdata \
		rng-tools \
		ca-certificates \
		libgcc \
		$(scanelf --needed --nobanner /usr/bin/ss* \
		| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
		| xargs -r apk info --installed \
		| sort -u) \
	&& /root/v2ray-plugin.sh "${TARGETPLATFORM}" \
	&& /root/xray-plugin.sh "${TARGETPLATFORM}" \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh

VOLUME /etc/shadowsocks-rust
ENV TZ=Asia/Shanghai
CMD [ "/usr/bin/ssservice", "server", "--log-without-time", "-c", "/etc/shadowsocks-rust/config.json" ]


================================================
FILE: docker/shadowsocks-rust/Dockerfile.architecture
================================================
# Dockerfile for shadowsocks-rust based alpine
# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:latest
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY config_sample.json /etc/shadowsocks-rust/config.json
RUN set -ex \
	&& runDeps="git build-base c-ares-dev autoconf automake libev-dev libtool libsodium-dev linux-headers mbedtls-dev pcre-dev openssl-dev cargo" \
	&& apk add --no-cache --virtual .build-deps ${runDeps} \
	&& mkdir -p /root/rust \
	&& cd /root/rust \
	&& VERSION=$(wget --no-check-certificate -qO- https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest | grep 'tag_name' | cut -d\" -f4) \
	&& git clone -b ${VERSION} --depth=1 https://github.com/shadowsocks/shadowsocks-rust.git . \
	&& cargo build --release --features "local-tun local-redir stream-cipher aead-cipher-2022" --verbose \
	&& cp -pv target/release/sslocal /usr/bin \
	&& cp -pv target/release/ssmanager /usr/bin \
	&& cp -pv target/release/ssserver /usr/bin \
	&& cp -pv target/release/ssservice /usr/bin \
	&& cp -pv target/release/ssurl /usr/bin \
	&& apk add --no-cache \
		tzdata \
		rng-tools \
		ca-certificates \
		libgcc \
		$(scanelf --needed --nobanner /usr/bin/ss* \
		| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
		| xargs -r apk info --installed \
		| sort -u) \
	&& apk del .build-deps \
	&& cd /root \
	&& rm -rf /root/rust \
	&& chmod +x /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/v2ray-plugin.sh "${TARGETPLATFORM}" \
	&& /root/xray-plugin.sh "${TARGETPLATFORM}" \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh

VOLUME /etc/shadowsocks-rust
ENV TZ=Asia/Shanghai
CMD [ "/usr/bin/ssservice", "server", "--log-without-time", "-c", "/etc/shadowsocks-rust/config.json" ]


================================================
FILE: docker/shadowsocks-rust/Dockerfile.debian
================================================
# Dockerfile for shadowsocks-rust based debian
# Copyright (C) 2020 - 2025 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM debian:trixie-slim
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY shadowsocks-rust-debian.sh /root/shadowsocks-rust-debian.sh
COPY config_sample.json /etc/shadowsocks-rust/config.json
RUN set -ex \
	&& apt-get update \
	&& apt-get install -y --no-install-recommends wget ca-certificates xz-utils \
	&& chmod +x /root/shadowsocks-rust-debian.sh \
	&& /root/shadowsocks-rust-debian.sh "${TARGETPLATFORM}" \
	&& rm -f /root/shadowsocks-rust-debian.sh \
	&& chmod +x /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& /root/v2ray-plugin.sh "${TARGETPLATFORM}" \
	&& /root/xray-plugin.sh "${TARGETPLATFORM}" \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& apt-get -y autoremove \
	&& apt-get -y clean \
	&& rm -rf /var/lib/apt/lists/*

VOLUME /etc/shadowsocks-rust
ENV TZ=Asia/Shanghai
CMD [ "/usr/bin/ssservice", "server", "--log-without-time", "-c", "/etc/shadowsocks-rust/config.json" ]


================================================
FILE: docker/shadowsocks-rust/Dockerfile_edge.alpine
================================================
# Dockerfile for shadowsocks-rust based alpine
# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

FROM alpine:edge
LABEL maintainer="Teddysun <i@teddysun.com>"

ARG TARGETPLATFORM
WORKDIR /root
COPY v2ray-plugin.sh /root/v2ray-plugin.sh
COPY xray-plugin.sh /root/xray-plugin.sh
COPY config_sample.json /etc/shadowsocks-rust/config.json
RUN set -ex \
	&& chmod +x /root/v2ray-plugin.sh /root/xray-plugin.sh \
	&& apk add --no-cache tzdata rng-tools ca-certificates shadowsocks-rust \
	&& /root/v2ray-plugin.sh "${TARGETPLATFORM}" \
	&& /root/xray-plugin.sh "${TARGETPLATFORM}" \
	&& rm -f /root/v2ray-plugin.sh /root/xray-plugin.sh

VOLUME /etc/shadowsocks-rust
ENV TZ=Asia/Shanghai
CMD [ "/usr/bin/ssservice", "server", "--log-without-time", "-c", "/etc/shadowsocks-rust/config.json" ]


================================================
FILE: docker/shadowsocks-rust/README.md
================================================
## Shadowsocks-rust Docker Image by Teddysun

![Shadowsocks](https://github.com/teddysun/shadowsocks_install/raw/master/shadowsocks.png)

[shadowsocks-rust][1] is a fast tunnel proxy that helps you bypass firewalls.

It is a port of [shadowsocks][2] created by [@zonyitoo](https://github.com/zonyitoo).

Based on alpine with latest version [shadowsocks-rust](https://github.com/shadowsocks/shadowsocks-rust) and [v2ray-plugin](https://github.com/teddysun/v2ray-plugin), [xray-plugin](https://github.com/teddysun/xray-plugin).

Docker images are built for quick deployment in various computing cloud providers.

For more information on docker and containerization technologies, refer to [official document][3].

## Prepare the host

If you need to install docker by yourself, follow the [official installation guide][4].

## Pull the image

```bash
$ docker pull teddysun/shadowsocks-rust
```

This pulls the latest release of shadowsocks-rust.

It can be found at [Docker Hub][5].

## Start a container

You **must create a configuration file**  `/etc/shadowsocks-rust/config.json` in host at first:

```
$ mkdir -p /etc/shadowsocks-rust
```

A sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp"
}
```

If you want to enable **v2ray-plugin**, a sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp",
    "plugin":"v2ray-plugin",
    "plugin_opts":"server"
}
```

If you want to enable **xray-plugin**, a sample in JSON like below:

```
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp",
    "plugin":"xray-plugin",
    "plugin_opts":"server"
}
```

For more `v2ray-plugin` configrations please visit v2ray-plugin [usage][6].

For more `xray-plugin` configrations please visit xray-plugin [usage][7].

This container with sample configuration `/etc/shadowsocks-rust/config.json`

There is an example to start a container that listens on `9000` (both TCP and UDP):

```bash
$ docker run -d -p 9000:9000 -p 9000:9000/udp --name ss-rust --restart=always -v /etc/shadowsocks-rust:/etc/shadowsocks-rust teddysun/shadowsocks-rust
```

**Warning**: The port number must be same as configuration and opened in firewall.

[1]: https://github.com/shadowsocks/shadowsocks-rust
[2]: https://shadowsocks.org/en/index.html
[3]: https://docs.docker.com/
[4]: https://docs.docker.com/install/
[5]: https://hub.docker.com/r/teddysun/shadowsocks-rust/
[6]: https://github.com/shadowsocks/v2ray-plugin#usage
[7]: https://github.com/teddysun/xray-plugin#usage

================================================
FILE: docker/shadowsocks-rust/build_v2ray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for build multi-architectures v2ray-plugin binary file
# 
# Supported architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x
# 
# Copyright (C) 2020 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/v2ray-plugin

cur_dir="$(pwd)"

COMMANDS=( git go )
for CMD in "${COMMANDS[@]}"; do
    if [ ! "$(command -v "${CMD}")" ]; then
        echo "${CMD} is not installed, please install it and try again" && exit 1
    fi
done

cd ${cur_dir}
git clone https://github.com/shadowsocks/v2ray-plugin.git
cd v2ray-plugin || exit 2

VERSION="$(git describe --tags)"
LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS=""
ARCHS=( 386 amd64 arm arm64 ppc64le s390x )
ARMS=( 6 7 )

for ARCH in ${ARCHS[@]}; do
    if [ "${ARCH}" = "arm" ]; then
        for V in ${ARMS[@]}; do
            echo "Building v2ray-plugin_linux_${ARCH}${V}"
            env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} GOARM=${V} go build -v -ldflags "${LDFLAGS}" -gcflags "${GCFLAGS}" -o ${cur_dir}/v2ray-plugin_linux_${ARCH}${V}
        done
    else
        echo "Building v2ray-plugin_linux_${ARCH}"
        env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -v -ldflags "${LDFLAGS}" -gcflags "${GCFLAGS}" -o ${cur_dir}/v2ray-plugin_linux_${ARCH}
    fi
done

# clean up
cd ${cur_dir} && rm -fr v2ray-plugin


================================================
FILE: docker/shadowsocks-rust/build_xray-plugin.sh
================================================
#!/bin/bash
#
# This is a Shell script for build multi-architectures xray-plugin binary file
# 
# Supported architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x
# 
# Copyright (C) 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/teddysun/xray-plugin

cur_dir="$(pwd)"

COMMANDS=( git go )
for CMD in "${COMMANDS[@]}"; do
    if [ ! "$(command -v "${CMD}")" ]; then
        echo "${CMD} is not installed, please install it and try again" && exit 1
    fi
done

cd ${cur_dir}
git clone https://github.com/teddysun/xray-plugin.git
cd xray-plugin || exit 2

VERSION="$(git describe --tags)"
LDFLAGS="-X main.VERSION=$VERSION -s -w"
ARCHS=( 386 amd64 arm arm64 ppc64le s390x )
ARMS=( 6 7 )

for ARCH in ${ARCHS[@]}; do
    if [ "${ARCH}" = "arm" ]; then
        for V in ${ARMS[@]}; do
            echo "Building xray-plugin_linux_${ARCH}${V}"
            env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} GOARM=${V} go build -v -trimpath -ldflags "${LDFLAGS}" -o ${cur_dir}/xray-plugin_linux_${ARCH}${V}
        done
    else
        echo "Building xray-plugin_linux_${ARCH}"
        env CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -v -trimpath -ldflags "${LDFLAGS}" -o ${cur_dir}/xray-plugin_linux_${ARCH}
    fi
done

# clean up
cd ${cur_dir} && rm -fr xray-plugin


================================================
FILE: docker/shadowsocks-rust/config_sample.json
================================================
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "method":"aes-256-gcm",
    "fast_open":true,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp"
}

================================================
FILE: docker/shadowsocks-rust/shadowsocks-rust-alpine.sh
================================================
#!/bin/sh
#
# This is a Shell script for shadowsocks-rust based alpine with Docker image
# 
# Copyright (C) 2019 - 2024 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="x86_64-unknown-linux-musl"
else
    case "$PLATFORM" in
        linux/386)
            ARCH=""
            ;;
        linux/amd64)
            ARCH="x86_64-unknown-linux-musl"
            ;;
        linux/arm/v6)
            ARCH="arm-unknown-linux-musleabi"
            ;;
        linux/arm/v7)
            ARCH="arm-unknown-linux-musleabihf"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="aarch64-unknown-linux-musl"
            ;;
        linux/ppc64le)
            ARCH=""
            ;;
        linux/s390x)
            ARCH=""
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
VERSION=$(wget --no-check-certificate -qO- https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest | grep 'tag_name' | cut -d\" -f4)
[ -z "${VERSION}" ] && echo "Error: Get shadowsocks-rust latest version failed" && exit 1
# Download shadowsocks-rust binary file
SHADOWSOCKS_RUST_FILE="shadowsocks-${VERSION}.${ARCH}.tar.xz"
SHADOWSOCKS_RUST_URL="https://github.com/shadowsocks/shadowsocks-rust/releases/download/${VERSION}/${SHADOWSOCKS_RUST_FILE}"
echo "Downloading shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE}"
wget -O ${SHADOWSOCKS_RUST_FILE} ${SHADOWSOCKS_RUST_URL} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE}" && exit 1
fi
echo "Download shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE} completed"
echo "Extracting ${SHADOWSOCKS_RUST_FILE}..."
tar Jxf ${SHADOWSOCKS_RUST_FILE} -C /usr/bin
chmod +x /usr/bin/ss*
rm -f ${SHADOWSOCKS_RUST_FILE}
echo "Install shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE} completed"


================================================
FILE: docker/shadowsocks-rust/shadowsocks-rust-debian.sh
================================================
#!/bin/sh
#
# This is a Shell script for shadowsocks-rust based debian with Docker image
# 
# Copyright (C) 2019 - 2024 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="x86_64-unknown-linux-gnu"
else
    case "$PLATFORM" in
        linux/386)
            ARCH=""
            ;;
        linux/amd64)
            ARCH="x86_64-unknown-linux-gnu"
            ;;
        linux/arm/v6)
            ARCH=""
            ;;
        linux/arm/v7)
            ARCH="arm-unknown-linux-gnueabihf"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="aarch64-unknown-linux-gnu"
            ;;
        linux/ppc64le)
            ARCH=""
            ;;
        linux/s390x)
            ARCH=""
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
VERSION=$(wget --no-check-certificate -qO- https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest | grep 'tag_name' | cut -d\" -f4)
[ -z "${VERSION}" ] && echo "Error: Get shadowsocks-rust latest version failed" && exit 1
# Download shadowsocks-rust binary file
SHADOWSOCKS_RUST_FILE="shadowsocks-${VERSION}.${ARCH}.tar.xz"
SHADOWSOCKS_RUST_URL="https://github.com/shadowsocks/shadowsocks-rust/releases/download/${VERSION}/${SHADOWSOCKS_RUST_FILE}"
echo "Downloading shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE}"
wget -O ${SHADOWSOCKS_RUST_FILE} ${SHADOWSOCKS_RUST_URL} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE}" && exit 1
fi
echo "Download shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE} completed"
echo "Extracting ${SHADOWSOCKS_RUST_FILE}..."
tar Jxf ${SHADOWSOCKS_RUST_FILE} -C /usr/bin
chmod +x /usr/bin/ss*
rm -f ${SHADOWSOCKS_RUST_FILE}
echo "Install shadowsocks-rust binary file: ${SHADOWSOCKS_RUST_FILE} completed"


================================================
FILE: docker/shadowsocks-rust/v2ray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for shadowsocks-libev supported SIP003 plugins based alpine with Docker image
# 
# Copyright (C) 2019 - 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/shadowsocks/v2ray-plugin
# https://github.com/teddysun/v2ray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download v2ray-plugin binary file
V2RAY_PLUGIN_FILE="v2ray-plugin_linux_${ARCH}"
echo "Downloading v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE}"
wget -O /usr/bin/v2ray-plugin https://dl.lamp.sh/files/${V2RAY_PLUGIN_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE}" && exit 1
fi
chmod +x /usr/bin/v2ray-plugin
echo "Download v2ray-plugin binary file: ${V2RAY_PLUGIN_FILE} completed"


================================================
FILE: docker/shadowsocks-rust/xray-plugin.sh
================================================
#!/bin/sh
#
# This is a Shell script for shadowsocks-rust supported SIP003 plugins based alpine with Docker image
# 
# Copyright (C) 2019 - 2021 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://github.com/teddysun/xray-plugin

PLATFORM=$1
if [ -z "$PLATFORM" ]; then
    ARCH="amd64"
else
    case "$PLATFORM" in
        linux/386)
            ARCH="386"
            ;;
        linux/amd64)
            ARCH="amd64"
            ;;
        linux/arm/v6)
            ARCH="arm6"
            ;;
        linux/arm/v7)
            ARCH="arm7"
            ;;
        linux/arm64|linux/arm64/v8)
            ARCH="arm64"
            ;;
        linux/ppc64le)
            ARCH="ppc64le"
            ;;
        linux/s390x)
            ARCH="s390x"
            ;;
        *)
            ARCH=""
            ;;
    esac
fi
[ -z "${ARCH}" ] && echo "Error: Not supported OS Architecture" && exit 1
# Download xray-plugin binary file
XRAY_PLUGIN_FILE="xray-plugin_linux_${ARCH}"
echo "Downloading xray-plugin binary file: ${XRAY_PLUGIN_FILE}"
wget -O /usr/bin/xray-plugin https://dl.lamp.sh/files/${XRAY_PLUGIN_FILE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: Failed to download xray-plugin binary file: ${XRAY_PLUGIN_FILE}" && exit 1
fi
chmod +x /usr/bin/xray-plugin
echo "Download xray-plugin binary file: ${XRAY_PLUGIN_FILE} completed"


================================================
FILE: haproxy.sh
================================================
#!/usr/bin/env bash
#
# System Required:  CentOS, Debian, Ubuntu
#
# Description: Install haproxy for Shadowsocks server
#
# Author: Teddysun <i@teddysun.com>
#
# Intro:  https://shadowsocks.be/10.html
#

cur_dir=`pwd`

[[ $EUID -ne 0 ]] && echo "Error: This script must be run as root!" && exit 1

clear
echo
echo "#############################################################"
echo "# Install haproxy for Shadowsocks server                    #"
echo "# Intro: https://shadowsocks.be/10.html                     #"
echo "# Author: Teddysun <i@teddysun.com>                         #"
echo "#############################################################"
echo

check_sys() {
    local checkType=$1
    local value=$2

    local release=''
    local systemPackage=''

    if [ -f /etc/redhat-release ]; then
        release="centos"
        systemPackage="yum"
    elif cat /etc/issue | grep -Eqi "debian"; then
        release="debian"
        systemPackage="apt"
    elif cat /etc/issue | grep -Eqi "ubuntu"; then
        release="ubuntu"
        systemPackage="apt"
    elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
        release="centos"
        systemPackage="yum"
    elif cat /proc/version | grep -Eqi "debian"; then
        release="debian"
        systemPackage="apt"
    elif cat /proc/version | grep -Eqi "ubuntu"; then
        release="ubuntu"
        systemPackage="apt"
    elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
        release="centos"
        systemPackage="yum"
    fi

    if [ ${checkType} == "sysRelease" ]; then
        if [ "$value" == "$release" ]; then
            return 0
        else
            return 1
        fi
    elif [ ${checkType} == "packageManager" ]; then
        if [ "$value" == "$systemPackage" ]; then
            return 0
        else
            return 1
        fi
    fi
}

install_check() {
    if check_sys packageManager yum || check_sys packageManager apt; then
        return 0
    else
        return 1
    fi
}

disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}

valid_ip(){
    local ip=$1
    local stat=1
    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return ${stat}
}

get_ip(){
    local IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip )
    [ ! -z ${IP} ] && echo ${IP} || echo
}

get_char(){
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}

# Pre-installation settings
pre_install(){
    if ! install_check; then
        echo "Your OS is not supported to run it."
        echo "Please change to CentOS 6+/Debian 7+/Ubuntu 12+ and try again."
        exit 1
    fi

    # Set haproxy config port
    while true
    do
    echo -e "Please enter a port for haproxy and Shadowsocks server [1-65535]"
    read -p "(Default port: 8989):" haproxyport
    [ -z "${haproxyport}" ] && haproxyport="8989"
    expr ${haproxyport} + 0 &>/dev/null
    if [ $? -eq 0 ]; then
        if [ ${haproxyport} -ge 1 ] && [ ${haproxyport} -le 65535 ]; then
            echo
            echo "---------------------------"
            echo "port = ${haproxyport}"
            echo "---------------------------"
            echo
            break
        else
            echo "Enter error! Please enter a correct number."
        fi
    else
        echo "Enter error! Please enter a correct number."
    fi
    done

    # Set haproxy config IPv4 address
    while :
    do
    echo -e "Please enter your Shadowsocks server's IPv4 address for haproxy"
    read -p "(IPv4 is):" haproxyip
    valid_ip ${haproxyip}
    if [ $? -eq 0 ]; then
        echo
        echo "---------------------------"
        echo "IP = ${haproxyip}"
        echo "---------------------------"
        echo
        break
    else
        echo "Enter error! Please enter correct IPv4 address."
    fi
    done

    echo
    echo "Press any key to start...or Press Ctrl+C to cancel"
    char=`get_char`

}

# Config haproxy
config_haproxy(){
    # Config DNS nameserver
    if ! grep -q "8.8.8.8" /etc/resolv.conf; then
        cp -p /etc/resolv.conf /etc/resolv.conf.bak
        echo "nameserver 8.8.8.8" > /etc/resolv.conf
        echo "nameserver 8.8.4.4" >> /etc/resolv.conf
    fi

    if [ -f /etc/haproxy/haproxy.cfg ]; then
        cp -p /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
    fi

    cat > /etc/haproxy/haproxy.cfg<<-EOF
global
    ulimit-n    51200
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    user        haproxy
    group       haproxy
    daemon

defaults
    mode                    tcp
    log                     global
    option                  dontlognull
    timeout connect         5s
    timeout client          1m
    timeout server          1m

frontend ss-${haproxyport}
        bind *:${haproxyport}
        default_backend ss-${haproxyport}
backend ss-${haproxyport}
        server server1 ${haproxyip}:${haproxyport} maxconn 20480
EOF
}

install(){
    # Install haproxy
    if check_sys packageManager yum; then
        yum install -y haproxy
    elif check_sys packageManager apt; then
        apt-get -y update
        apt-get install -y haproxy
    fi

    if [ -d /etc/haproxy ]; then
        echo "haproxy install success."

        echo "Config haproxy start..."
        config_haproxy
        echo "Config haproxy completed..."

        if check_sys packageManager yum; then
            chkconfig --add haproxy
            chkconfig haproxy on
        elif check_sys packageManager apt; then
            update-rc.d haproxy defaults
        fi

        # Start haproxy
        service haproxy start
        if [ $? -eq 0 ]; then
            echo "haproxy start success..."
        else
            echo "haproxy start failure..."
        fi
    else
        echo
        echo "haproxy install failed."
        exit 1
    fi

    sleep 3
    # restart haproxy
    service haproxy restart
    # Active Internet connections confirm
    netstat -nxtlp
    echo
    echo "Congratulations, haproxy install completed."
    echo -e "Your haproxy Server IP: \033[41;37m $(get_ip) \033[0m"
    echo -e "Your haproxy Server port: \033[41;37m ${haproxyport} \033[0m"
    echo -e "Your Input Shadowsocks IP: \033[41;37m ${haproxyip} \033[0m"
    echo
    echo "Welcome to visit: https://shadowsocks.be/10.html"
    echo "Enjoy it."
    echo
}


# Install haproxy
install_haproxy(){
    disable_selinux
    pre_install
    install
}

# Initialization step
install_haproxy 2>&1 | tee ${cur_dir}/haproxy_for_shadowsocks.log


================================================
FILE: sample_config/shadowsocks-go/config.json
================================================
{
    "port_password":{
         "9000":"password0",
         "9001":"password1",
         "9002":"password2",
         "9003":"password3",
         "9004":"password4"
    },
    "method":"aes-256-cfb",
    "timeout":300
}

================================================
FILE: sample_config/shadowsocks-libev/config.json
================================================
{
    "server":"0.0.0.0",
    "server_port":9000,
    "password":"password0",
    "timeout":300,
    "user":"nobody",
    "method":"aes-256-gcm",
    "fast_open":false,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp"
}

================================================
FILE: sample_config/shadowsocks-manager/config.json
================================================
{
    "server":"0.0.0.0",
    "port_password":{
         "9000":"password0",
         "9001":"password1",
         "9002":"password2",
         "9003":"password3",
         "9004":"password4"
    },
    "timeout":300,
    "user":"nobody",
    "method":"aes-256-gcm",
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp"
}

================================================
FILE: sample_config/shadowsocks-python/config.json
================================================
{
    "server":"0.0.0.0",
    "local_address":"127.0.0.1",
    "local_port":1080,
    "port_password":{
         "9000":"password0",
         "9001":"password1",
         "9002":"password2",
         "9003":"password3",
         "9004":"password4"
    },
    "timeout":300,
    "method":"aes-256-gcm",
    "fast_open": false
}

================================================
FILE: sample_config/shadowsocks-r/config.json
================================================
{
    "server":"0.0.0.0",
    "server_ipv6": "[::]",
    "local_address":"127.0.0.1",
    "local_port":1080,
    "port_password":{
        "9000":"password0",
        "9001":"password1",
        "9002":"password2",
        "9003":"password3",
        "9004":"password4"
    },
    "timeout":300,
    "method":"aes-256-cfb",
    "protocol": "auth_chain_a",
    "protocol_param": "",
    "obfs": "http_simple_compatible",
    "obfs_param": "",
    "redirect": "",
    "dns_ipv6": false,
    "fast_open": false,
    "workers": 1
}

================================================
FILE: shadowsocks
================================================
#!/bin/bash
# chkconfig: 2345 90 10
# description: A secure socks5 proxy, designed to protect your Internet traffic.

### BEGIN INIT INFO
# Provides:          Shadowsocks
# Required-Start:    $network $syslog
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the Shadowsocks server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

NAME=Shadowsocks
if [ -f /usr/bin/ssserver ]; then
    DAEMON=/usr/bin/ssserver
elif [ -f /usr/local/bin/ssserver ]; then
    DAEMON=/usr/local/bin/ssserver
fi
if [ -f /etc/shadowsocks-python/config.json ]; then
    CONF=/etc/shadowsocks-python/config.json
elif [ -f /etc/shadowsocks.json ]; then
    CONF=/etc/shadowsocks.json
fi
RETVAL=0

check_running(){
    PID=$(ps -ef | grep -v grep | grep -i "${DAEMON}" | awk '{print $2}')
    if [ -n "$PID" ]; then
        return 0
    else
        return 1
    fi
}

do_start(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is already running..."
        exit 0
    else
        $DAEMON -c $CONF -d start
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Starting $NAME success"
        else
            echo "Starting $NAME failed"
        fi
    fi
}

do_stop(){
    check_running
    if [ $? -eq 0 ]; then
        $DAEMON -c $CONF -d stop
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Stopping $NAME success"
        else
            echo "Stopping $NAME failed"
        fi
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_status(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is running..."
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_restart(){
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RETVAL=1
    ;;
esac

exit $RETVAL


================================================
FILE: shadowsocks-all.sh
================================================
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#
# Auto install Shadowsocks Server (libev and rust) with v2ray-plugin and xray-plugin
#
# Copyright (C) 2016-2026 Teddysun <i@teddysun.com>
#
# System Required:  CentOS/RHEL 8+, Debian 11+, Ubuntu 20.04+
#
# Reference URL:
# https://github.com/shadowsocks/shadowsocks-libev
# https://github.com/shadowsocks/shadowsocks-rust
# https://github.com/teddysun/v2ray-plugin
# https://github.com/teddysun/xray-plugin
#
# Thanks:
# @madeye     <https://github.com/madeey>
# @zonyitoo   <https://github.com/zonyitoo>
#
# Intro:  https://teddysun.com/486.html

red='\e[0;31m'
green='\e[0;32m'
yellow='\e[0;33m'
plain='\e[0m'

[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1

cur_dir=$( pwd )
software=(Shadowsocks-libev Shadowsocks-rust)
plugins=(None v2ray-plugin xray-plugin)

shadowsocks_libev_config='/etc/shadowsocks/shadowsocks-libev-config.json'
shadowsocks_rust_config='/etc/shadowsocks/shadowsocks-rust-config.json'

# Stream Ciphers
common_ciphers=(
aes-256-gcm
aes-192-gcm
aes-128-gcm
chacha20-ietf-poly1305
xchacha20-ietf-poly1305
)

rust_ciphers=(
aes-256-gcm
aes-192-gcm
aes-128-gcm
chacha20-ietf-poly1305
xchacha20-ietf-poly1305
2022-blake3-aes-256-gcm
2022-blake3-aes-128-gcm
2022-blake3-chacha20-poly1305
)

# RHEL repo URL
rhel_repo_url='https://dl.lamp.sh/shadowsocks/rhel/teddysun.repo'
rhel_repo_url_2='https://dl.lamp.sh/linux/rhel/teddysun_linux.repo'

# Debian/Ubuntu GPG key URL
debian_gpg_url='https://dl.lamp.sh/shadowsocks/DEB-GPG-KEY-Teddysun'

disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}

check_sys(){
    local checkType=$1
    local value=$2

    local release=''
    local systemPackage=''

    if [[ -f /etc/redhat-release ]]; then
        release='centos'
        systemPackage='dnf'
    elif grep -Eqi 'debian|raspbian' /etc/issue; then
        release='debian'
        systemPackage='apt'
    elif grep -Eqi 'ubuntu' /etc/issue; then
        release='ubuntu'
        systemPackage='apt'
    elif grep -Eqi 'centos|red hat|redhat' /etc/issue; then
        release='centos'
        systemPackage='dnf'
    elif grep -Eqi 'debian|raspbian' /proc/version; then
        release='debian'
        systemPackage='apt'
    elif grep -Eqi 'ubuntu' /proc/version; then
        release='ubuntu'
        systemPackage='apt'
    elif grep -Eqi 'centos|red hat|redhat' /proc/version; then
        release='centos'
        systemPackage='dnf'
    fi

    if [[ "${checkType}" == 'sysRelease' ]]; then
        if [ "${value}" == "${release}" ]; then
            return 0
        else
            return 1
        fi
    elif [[ "${checkType}" == 'packageManager' ]]; then
        if [ "${value}" == "${systemPackage}" ]; then
            return 0
        else
            return 1
        fi
    fi
}

get_ip(){
    local IP
    IP=$(ip addr | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -E -v '^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\.' | head -n 1)
    [ -z "${IP}" ] && IP=$(wget -qO- -t1 -T2 http://ipv4.icanhazip.com)
    [ -z "${IP}" ] && IP=$(wget -qO- -t1 -T2 http://ipinfo.io/ip)
    echo "${IP}"
}

get_ipv6(){
    local ipv6
    ipv6=$(wget -qO- -t1 -T2 http://ipv6.icanhazip.com)
    [ -z "${ipv6}" ] && return 1
    return 0
}

get_opsy(){
    [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
    [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
    [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}

get_char(){
    SAVEDSTTY=$(stty -g)
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty "$SAVEDSTTY"
}

is_valid_port() {
    local port="$1"
    [[ "$port" =~ ^[0-9]+$ ]] || return 1
    (( port >= 1 && port <= 65535 )) || return 1
    return 0
}

install_check(){
    if check_sys packageManager dnf || check_sys packageManager apt; then
        return 0
    else
        return 1
    fi
}

install_select(){
    if ! install_check; then
        echo -e "[${red}Error${plain}] Your OS is not supported to run it!"
        echo 'Please change to CentOS/RHEL 8+, Debian 11+, or Ubuntu 20.04+ and try again.'
        exit 1
    fi

    clear
    while true
    do
    echo  "Which Shadowsocks server you'd select:"
    for ((i=1;i<=${#software[@]};i++ )); do
        hint="${software[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -r -p "Please enter a number (Default ${software[0]}):" selected
    [ -z "${selected}" ] && selected='1'
    case "${selected}" in
        1|2)
        echo
        echo "You choose = ${software[${selected}-1]}"
        echo
        break
        ;;
        *)
        echo -e "[${red}Error${plain}] Please only enter a number [1-2]"
        ;;
    esac
    done
}

install_prepare_password(){
    echo "Please enter password for ${software[${selected}-1]}"
    read -r -p '(Default password: teddysun.com):' shadowsockspwd
    [ -z "${shadowsockspwd}" ] && shadowsockspwd='teddysun.com'
    echo
    echo "password = ${shadowsockspwd}"
    echo
}

install_prepare_port() {
    while true
    do
    dport=$(shuf -i 9000-19999 -n 1)
    echo -e "Please enter a port for ${software[${selected}-1]} [1-65535]"
    read -r -p "(Default port: ${dport}):" shadowsocksport
    [ -z "${shadowsocksport}" ] && shadowsocksport=${dport}
    if is_valid_port "${shadowsocksport}"; then
        echo
        echo "port = ${shadowsocksport}"
        echo
        break
    fi
    echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]"
    done
}

install_prepare_cipher(){
    while true
    do
    echo -e "Please select stream cipher for ${software[${selected}-1]}:"

    if [ "${selected}" == '1' ]; then
        for ((i=1;i<=${#common_ciphers[@]};i++ )); do
            hint="${common_ciphers[$i-1]}"
            echo -e "${green}${i}${plain}) ${hint}"
        done
        read -r -p "Which cipher you'd select(Default: ${common_ciphers[0]}):" pick
        [ -z "${pick}" ] && pick=1
        if [[ "${pick}" =~ [^0-9] ]]; then
            echo -e "[${red}Error${plain}] Please enter a number"
            continue
        fi
        if [[ "${pick}" -lt 1 || "${pick}" -gt ${#common_ciphers[@]} ]]; then
            echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#common_ciphers[@]}"
            continue
        fi
        shadowsockscipher=${common_ciphers[${pick}-1]}
    elif [ "${selected}" == '2' ]; then
        for ((i=1;i<=${#rust_ciphers[@]};i++ )); do
            hint="${rust_ciphers[$i-1]}"
            echo -e "${green}${i}${plain}) ${hint}"
        done
        read -r -p "Which cipher you'd select(Default: ${rust_ciphers[0]}):" pick
        [ -z "${pick}" ] && pick=1
        if [[ "${pick}" =~ [^0-9] ]]; then
            echo -e "[${red}Error${plain}] Please enter a number"
            continue
        fi
        if [[ "${pick}" -lt 1 || "${pick}" -gt ${#rust_ciphers[@]} ]]; then
            echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#rust_ciphers[@]}"
            continue
        fi
        shadowsockscipher=${rust_ciphers[${pick}-1]}
    fi

    echo
    echo "cipher = ${shadowsockscipher}"
    echo
    break
    done
}

install_prepare_plugin(){
    while true
    do
    echo -e "Please select SIP003 plugin for ${software[${selected}-1]}:"
    for ((i=1;i<=${#plugins[@]};i++ )); do
        hint="${plugins[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -r -p "Which plugin you'd select (Default: ${plugins[0]}):" pick
    [ -z "${pick}" ] && pick=1
    if [[ "${pick}" =~ [^0-9] ]]; then
        echo -e "[${red}Error${plain}] Please enter a number"
        continue
    fi
    if [[ "${pick}" -lt 1 || "${pick}" -gt ${#plugins[@]} ]]; then
        echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#plugins[@]}"
        continue
    fi
    plugin_name=${plugins[${pick}-1]}
    echo
    echo "plugin = ${plugin_name}"
    echo
    break
    done

    if [ "${plugin_name}" != "None" ]; then
        install_prepare_plugin_options
    fi
}

install_prepare_plugin_options(){
    echo "Please enter plugin options (e.g., for v2ray-plugin/xray-plugin):"
    echo "Examples:"
    echo "  - No TLS: server"
    echo "  - With TLS: server;tls;host=yourdomain.com"
    echo "  - With TLS and path: server;tls;host=yourdomain.com;path=/ws"
    read -r -p '(Default: server):' plugin_opts
    [ -z "${plugin_opts}" ] && plugin_opts='server'
    echo
    echo "plugin_opts = ${plugin_opts}"
    echo
}

install_prepare(){
    install_prepare_password
    install_prepare_port
    install_prepare_cipher
    install_prepare_plugin

    echo
    echo 'Press any key to start...or Press Ctrl+C to cancel'
    get_char > /dev/null
}

add_rhel_repo(){
    echo -e "[${green}Info${plain}] Adding Teddysun Shadowsocks Repository for RHEL..."
    dnf install -y yum-utils epel-release > /dev/null 2>&1
    dnf config-manager --set-enabled epel > /dev/null 2>&1
    dnf config-manager --add-repo ${rhel_repo_url} > /dev/null 2>&1
    dnf config-manager --add-repo ${rhel_repo_url_2} > /dev/null 2>&1
    if [ -f "/etc/yum.repos.d/teddysun.repo" ] && [ -f "/etc/yum.repos.d/teddysun_linux.repo" ]; then
        echo -e "[${green}Info${plain}] Repository added successfully."
        dnf makecache > /dev/null 2>&1
    else
        echo -e "[${red}Error${plain}] Failed to add repository."
        exit 1
    fi
}

add_debian_repo(){
    local distro codename
    echo -e "[${green}Info${plain}] Adding Teddysun Shadowsocks Repository for Debian/Ubuntu..."
    apt-get update > /dev/null 2>&1
    apt-get -y install lsb-release ca-certificates curl gnupg > /dev/null 2>&1
    curl -fsSL ${debian_gpg_url} | gpg --dearmor --yes -o /usr/share/keyrings/deb-gpg-key-teddysun.gpg > /dev/null 2>&1
    chmod a+r /usr/share/keyrings/deb-gpg-key-teddysun.gpg
    
    distro=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
    codename=$(lsb_release -sc)
    
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/deb-gpg-key-teddysun.gpg] https://dl.lamp.sh/shadowsocks/${distro}/ ${codename} main" > /etc/apt/sources.list.d/teddysun.list
    
    if [ -f "/etc/apt/sources.list.d/teddysun.list" ]; then
        echo -e "[${green}Info${plain}] Repository added successfully."
        apt-get update > /dev/null 2>&1
    else
        echo -e "[${red}Error${plain}] Failed to add repository."
        exit 1
    fi
}

install_dependencies(){
    echo -e "[${green}Info${plain}] Checking and installing dependencies..."
    if check_sys packageManager dnf; then
        dnf install -y qrencode > /dev/null 2>&1
    elif check_sys packageManager apt; then
        apt-get install -y qrencode > /dev/null 2>&1
    fi
}

install_shadowsocks_libev(){
    local distro codename
    echo -e "[${green}Info${plain}] Installing ${software[0]}..."
    if check_sys packageManager dnf; then
        dnf install -y shadowsocks-libev > /dev/null 2>&1
    elif check_sys packageManager apt; then
        distro=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
        codename=$(lsb_release -sc)
        if [ "${distro}" == "debian" ]; then
            apt-get install -y "shadowsocks-libev=3.3.6-2~debian.$(lsb_release -sr | cut -d. -f1)~${codename}" > /dev/null 2>&1
        else
            apt-get install -y "shadowsocks-libev=3.3.6-2~ubuntu.$(lsb_release -sr | cut -d. -f1)~${codename}" > /dev/null 2>&1
        fi
    fi
    
    if [ ! -f "/usr/bin/ss-server" ]; then
        echo -e "[${red}Error${plain}] ${software[0]} installation failed."
        exit 1
    fi
}

install_shadowsocks_rust(){
    echo -e "[${green}Info${plain}] Installing ${software[1]}..."
    if check_sys packageManager dnf; then
        dnf install -y shadowsocks-rust > /dev/null 2>&1
    elif check_sys packageManager apt; then
        apt-get install -y shadowsocks-rust > /dev/null 2>&1
    fi
    
    if [ ! -f "/usr/bin/ssservice" ]; then
        echo -e "[${red}Error${plain}] ${software[1]} installation failed."
        exit 1
    fi
}

install_plugin(){
    if [ "${plugin_name}" == "None" ]; then
        return 0
    fi
    
    echo -e "[${green}Info${plain}] Installing ${plugin_name}..."
    if check_sys packageManager dnf; then
        dnf install -y "${plugin_name}" > /dev/null 2>&1
    elif check_sys packageManager apt; then
        apt-get install -y "${plugin_name}" > /dev/null 2>&1
    fi
    RT=$?
    if [ ${RT} -ne 0 ]; then
        echo -e "[${red}Error${plain}] ${plugin_name} installation failed."
        exit 1
    fi
}

config_shadowsocks_libev(){
    local server_value="\"0.0.0.0\""
    if get_ipv6; then
        server_value="[\"[::0]\",\"0.0.0.0\"]"
    fi

    mkdir -p "$(dirname ${shadowsocks_libev_config})"
    
    if [ "${plugin_name}" != "None" ]; then
        cat > ${shadowsocks_libev_config}<<-EOF
{
    "server":${server_value},
    "server_port":${shadowsocksport},
    "password":"${shadowsockspwd}",
    "timeout":300,
    "method":"${shadowsockscipher}",
    "fast_open":false,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp",
    "plugin":"${plugin_name}",
    "plugin_opts":"${plugin_opts}"
}
EOF
    else
        cat > ${shadowsocks_libev_config}<<-EOF
{
    "server":${server_value},
    "server_port":${shadowsocksport},
    "password":"${shadowsockspwd}",
    "timeout":300,
    "method":"${shadowsockscipher}",
    "fast_open":false,
    "nameserver":"8.8.8.8",
    "mode":"tcp_and_udp"
}
EOF
    fi
}

config_shadowsocks_rust(){
    local server_value="\"0.0.0.0\""
    if get_ipv6; then
        server_value="[\"[::0]\",\"0.0.0.0\"]"
    fi

    mkdir -p "$(dirname ${shadowsocks_rust_config})"
    
    if [ "${plugin_name}" != "None" ]; then
        cat > ${shadowsocks_rust_config}<<-EOF
{
    "server":${server_value},
    "server_port":${shadowsocksport},
    "password":"${shadowsockspwd}",
    "timeout":300,
    "method":"${shadowsockscipher}",
    "fast_open":false,
    "mode":"tcp_and_udp",
    "plugin":"${plugin_name}",
    "plugin_opts":"${plugin_opts}"
}
EOF
    else
        cat > ${shadowsocks_rust_config}<<-EOF
{
    "server":${server_value},
    "server_port":${shadowsocksport},
    "password":"${shadowsockspwd}",
    "timeout":300,
    "method":"${shadowsockscipher}",
    "fast_open":false,
    "mode":"tcp_and_udp"
}
EOF
    fi
}

config_firewall(){
    if check_sys packageManager dnf; then
        if systemctl status firewalld > /dev/null 2>&1; then
            default_zone=$(firewall-cmd --get-default-zone)
            firewall-cmd --permanent --zone="${default_zone}" --add-port="${shadowsocksport}"/tcp > /dev/null 2>&1
            firewall-cmd --permanent --zone="${default_zone}" --add-port="${shadowsocksport}"/udp > /dev/null 2>&1
            firewall-cmd --reload > /dev/null 2>&1
            echo -e "[${green}Info${plain}] Firewall port ${shadowsocksport} opened."
        else
            echo -e "[${yellow}Warning${plain}] firewalld is not running, please open port ${shadowsocksport} manually if necessary."
        fi
    fi
    if check_sys packageManager apt; then
        if ufw status &>/dev/null; then
            ufw allow "${shadowsocksport}"/tcp
            ufw allow "${shadowsocksport}"/udp
        else
            echo -e "[${yellow}Warning${plain}] ufw is not running, please open port ${shadowsocksport} manually if necessary."
        fi
    fi
}

start_shadowsocks_libev(){
    systemctl daemon-reload
    systemctl start shadowsocks-libev-server
    systemctl enable shadowsocks-libev-server > /dev/null 2>&1
}

start_shadowsocks_rust(){
    systemctl daemon-reload
    systemctl start shadowsocks-rust-server
    systemctl enable shadowsocks-rust-server > /dev/null 2>&1
}

install_completed_libev(){
    clear
    echo
    echo -e "Congratulations, ${green}${software[0]}${plain} server install completed!"
    echo -e "Your Server IP        : ${red} $(get_ip) ${plain}"
    echo -e "Your Server Port      : ${red} ${shadowsocksport} ${plain}"
    echo -e "Your Password         : ${red} ${shadowsockspwd} ${plain}"
    echo -e "Your Encryption Method: ${red} ${shadowsockscipher} ${plain}"
    if [ "${plugin_name}" != "None" ]; then
        echo -e "Your Plugin           : ${red} ${plugin_name} ${plain}"
        echo -e "Your Plugin Options   : ${red} ${plugin_opts} ${plain}"
    fi
}

install_completed_rust(){
    clear
    echo
    echo -e "Congratulations, ${green}${software[1]}${plain} server install completed!"
    echo -e "Your Server IP        : ${red} $(get_ip) ${plain}"
    echo -e "Your Server Port      : ${red} ${shadowsocksport} ${plain}"
    echo -e "Your Password         : ${red} ${shadowsockspwd} ${plain}"
    echo -e "Your Encryption Method: ${red} ${shadowsockscipher} ${plain}"
    if [ "${plugin_name}" != "None" ]; then
        echo -e "Your Plugin           : ${red} ${plugin_name} ${plain}"
        echo -e "Your Plugin Options   : ${red} ${plugin_opts} ${plain}"
    fi
}

qr_generate_libev(){
    if [ "$(command -v qrencode)" ]; then
        local tmp qr_code plugin_encoded
        if [ "${plugin_name}" != "None" ]; then
            # SIP003 URL format with plugin
            tmp=$(echo -n "${shadowsockscipher}:${shadowsockspwd}" | base64 -w0 | sed 's/=//g')
            plugin_encoded=$(echo -n "${plugin_name};${plugin_opts}" | base64 -w0 | sed 's/=//g')
            qr_code="ss://${tmp}@$(get_ip):${shadowsocksport}/?plugin=${plugin_encoded}"
        else
            tmp=$(echo -n "${shadowsockscipher}:${shadowsockspwd}@$(get_ip):${shadowsocksport}" | base64 -w0)
            qr_code="ss://${tmp}"
        fi
        echo
        echo 'Your QR Code: (For Shadowsocks Windows, OSX, Android and iOS clients)'
        echo -e "${green} ${qr_code} ${plain}"
        echo -n "${qr_code}" | qrencode -s8 -o "${cur_dir}"/shadowsocks_libev_qr.png
        echo 'Your QR Code has been saved as a PNG file path:'
        echo -e "${green} ${cur_dir}/shadowsocks_libev_qr.png ${plain}"
    fi
}

qr_generate_rust(){
    if [ "$(command -v qrencode)" ]; then
        local tmp qr_code plugin_encoded
        if [ "${plugin_name}" != "None" ]; then
            # SIP003 URL format with plugin
            tmp=$(echo -n "${shadowsockscipher}:${shadowsockspwd}" | base64 -w0 | sed 's/=//g')
            plugin_encoded=$(echo -n "${plugin_name};${plugin_opts}" | base64 -w0 | sed 's/=//g')
            qr_code="ss://${tmp}@$(get_ip):${shadowsocksport}/?plugin=${plugin_encoded}"
        else
            tmp=$(echo -n "${shadowsockscipher}:${shadowsockspwd}@$(get_ip):${shadowsocksport}" | base64 -w0)
            qr_code="ss://${tmp}"
        fi
        echo
        echo 'Your QR Code: (For Shadowsocks Windows, OSX, Android and iOS clients)'
        echo -e "${green} ${qr_code} ${plain}"
        echo -n "${qr_code}" | qrencode -s8 -o "${cur_dir}"/shadowsocks_rust_qr.png
        echo 'Your QR Code has been saved as a PNG file path:'
        echo -e "${green} ${cur_dir}/shadowsocks_rust_qr.png ${plain}"
    fi
}

install_main(){
    if   [ "${selected}" == '1' ]; then
        install_shadowsocks_libev
        install_plugin
        config_shadowsocks_libev
        start_shadowsocks_libev
        install_completed_libev
        qr_generate_libev
    elif [ "${selected}" == '2' ]; then
        install_shadowsocks_rust
        install_plugin
        config_shadowsocks_rust
        start_shadowsocks_rust
        install_completed_rust
        qr_generate_rust
    fi

    echo
    echo 'Welcome to visit: https://teddysun.com/486.html'
    echo 'Enjoy it!'
    echo
}

install_shadowsocks(){
    disable_selinux
    install_select
    install_prepare
    
    if check_sys packageManager dnf; then
        add_rhel_repo
    elif check_sys packageManager apt; then
        add_debian_repo
    fi
    
    install_dependencies
    config_firewall
    install_main
}

uninstall_shadowsocks_libev(){
    echo -e "Are you sure uninstall ${red}${software[0]}${plain}? [y/n]"
    read -r -p '(default: n):' answer
    [ -z "${answer}" ] && answer='n'
    if [ "${answer}" == 'y' ] || [ "${answer}" == 'Y' ]; then
        systemctl stop shadowsocks-libev-server > /dev/null 2>&1
        systemctl disable shadowsocks-libev-server > /dev/null 2>&1
        if check_sys packageManager dnf; then
            dnf remove -y shadowsocks-libev v2ray-plugin xray-plugin > /dev/null 2>&1
        elif check_sys packageManager apt; then
            apt-get remove -y shadowsocks-libev v2ray-plugin xray-plugin > /dev/null 2>&1
        fi
        rm -f ${shadowsocks_libev_config}
        echo -e "[${green}Info${plain}] ${software[0]} uninstall success"
    else
        echo
        echo -e "[${green}Info${plain}] ${software[0]} uninstall cancelled, nothing to do..."
        echo
    fi
}

uninstall_shadowsocks_rust(){
    echo -e "Are you sure uninstall ${red}${software[1]}${plain}? [y/n]"
    read -r -p '(default: n):' answer
    [ -z "${answer}" ] && answer='n'
    if [ "${answer}" == 'y' ] || [ "${answer}" == 'Y' ]; then
        systemctl stop shadowsocks-rust-server > /dev/null 2>&1
        systemctl disable shadowsocks-rust-server > /dev/null 2>&1
        if check_sys packageManager dnf; then
            dnf remove -y shadowsocks-rust v2ray-plugin xray-plugin > /dev/null 2>&1
        elif check_sys packageManager apt; then
            apt-get remove -y shadowsocks-rust v2ray-plugin xray-plugin > /dev/null 2>&1
        fi
        rm -f ${shadowsocks_rust_config}
        echo -e "[${green}Info${plain}] ${software[1]} uninstall success"
    else
        echo
        echo -e "[${green}Info${plain}] ${software[1]} uninstall cancelled, nothing to do..."
        echo
    fi
}

uninstall_shadowsocks(){
    while true
    do
    echo 'Which Shadowsocks server you want to uninstall?'
    for ((i=1;i<=${#software[@]};i++ )); do
        hint="${software[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -r -p 'Please enter a number [1-2]:' un_select
    case "${un_select}" in
        1|2)
        echo
        echo "You choose = ${software[${un_select}-1]}"
        echo
        break
        ;;
        *)
        echo -e "[${red}Error${plain}] Please only enter a number [1-2]"
        ;;
    esac
    done

    if   [ "${un_select}" == '1' ]; then
        uninstall_shadowsocks_libev
    elif [ "${un_select}" == '2' ]; then
        uninstall_shadowsocks_rust
    fi
}

# Initialization step
action=$1
[ -z "$1" ] && action=install
case "${action}" in
    install)
        install_shadowsocks
        ;;
    uninstall)
        uninstall_shadowsocks
        ;;
    *)
        echo "Arguments error! [${action}]"
        echo "Usage: $(basename "$0") [install|uninstall]"
        ;;
esac


================================================
FILE: shadowsocks-crond.sh
================================================
#!/usr/bin/env bash
#=================================================================#
#   System Required:  CentOS, Debian, Ubuntu                      #
#   Description: Check Shadowsocks Server is running or not       #
#   Author: Teddysun <i@teddysun.com>                             #
#   Visit: https://shadowsocks.be/6.html                          #
#=================================================================#

name=(Shadowsocks Shadowsocks-Python ShadowsocksR Shadowsocks-Go Shadowsocks-libev)
path=/var/log
[[ ! -d ${path} ]] && mkdir -p ${path}
log=${path}/shadowsocks-crond.log

shadowsocks_init[0]=/etc/init.d/shadowsocks
shadowsocks_init[1]=/etc/init.d/shadowsocks-python
shadowsocks_init[2]=/etc/init.d/shadowsocks-r
shadowsocks_init[3]=/etc/init.d/shadowsocks-go
shadowsocks_init[4]=/etc/init.d/shadowsocks-libev

i=0
for init in "${shadowsocks_init[@]}"; do
    pid=""
    if [ -f ${init} ]; then
        ss_status=$(${init} status)
        if [ $? -eq 0 ]; then
            pid=$(echo "$ss_status" | sed -e 's/[^0-9]*//g')
        fi

        if [ -z "${pid}" ]; then
            echo "$(date +'%Y-%m-%d %H:%M:%S') ${name[$i]} is not running" >> ${log}
            echo "$(date +'%Y-%m-%d %H:%M:%S') Starting ${name[$i]}" >> ${log}
            ${init} start &>/dev/null
            if [ $? -eq 0 ]; then
                echo "$(date +'%Y-%m-%d %H:%M:%S') ${name[$i]} start success" >> ${log}
            else
                echo "$(date +'%Y-%m-%d %H:%M:%S') ${name[$i]} start failed" >> ${log}
            fi
        else
            echo "$(date +'%Y-%m-%d %H:%M:%S') ${name[$i]} is running with pid $pid" >> ${log}
        fi
    
    fi
    ((i++))
done


================================================
FILE: shadowsocks-debian
================================================
#!/bin/bash

### BEGIN INIT INFO
# Provides:          Shadowsocks
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the Shadowsocks server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

NAME=Shadowsocks
if [ -f /usr/bin/ssserver ]; then
    DAEMON=/usr/bin/ssserver
elif [ -f /usr/local/bin/ssserver ]; then
    DAEMON=/usr/local/bin/ssserver
fi
if [ -f /etc/shadowsocks-python/config.json ]; then
    CONF=/etc/shadowsocks-python/config.json
elif [ -f /etc/shadowsocks.json ]; then
    CONF=/etc/shadowsocks.json
fi
RETVAL=0

check_running(){
    PID=$(ps -ef | grep -v grep | grep -i "${DAEMON}" | awk '{print $2}')
    if [ -n "$PID" ]; then
        return 0
    else
        return 1
    fi
}

do_start(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is already running..."
        exit 0
    else
        $DAEMON -c $CONF -d start
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Starting $NAME success"
        else
            echo "Starting $NAME failed"
        fi
    fi
}

do_stop(){
    check_running
    if [ $? -eq 0 ]; then
        $DAEMON -c $CONF -d stop
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Stopping $NAME success"
        else
            echo "Stopping $NAME failed"
        fi
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_status(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is running..."
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_restart(){
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RETVAL=1
    ;;
esac

exit $RETVAL


================================================
FILE: shadowsocks-go
================================================
#!/bin/bash
# chkconfig: 2345 90 10
# description: A secure socks5 proxy, designed to protect your Internet traffic.

### BEGIN INIT INFO
# Provides:          Shadowsocks-go
# Required-Start:    $network $syslog
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the Shadowsocks-go server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

# Source function library
. /etc/rc.d/init.d/functions

# Check that networking is up.
[ ${NETWORKING} ="yes" ] || exit 0

NAME=Shadowsocks-go
DAEMON=/usr/bin/shadowsocks-server
if [ -f /etc/shadowsocks-go/config.json ]; then
    CONF=/etc/shadowsocks-go/config.json
elif [ -f /etc/shadowsocks/config.json ]; then
    CONF=/etc/shadowsocks/config.json
fi
PID_DIR=/var/run
PID_FILE=$PID_DIR/shadowsocks-go.pid
RET_VAL=0

[ -x $DAEMON ] || exit 0

if [ ! -d $PID_DIR ]; then
    mkdir -p $PID_DIR
    if [ $? -ne 0 ]; then
        echo "Creating PID directory $PID_DIR failed"
        exit 1
    fi
fi

if [ ! -f $CONF ]; then
    echo "$NAME config file $CONF not found"
    exit 1
fi

check_running() {
    if [ -r $PID_FILE ]; then
        read PID < $PID_FILE
        if [ -d "/proc/$PID" ]; then
            return 0
        else
            rm -f $PID_FILE
            return 1
        fi
    else
        return 2
    fi
}

do_status() {
    check_running
    case $? in
        0)
        echo "$NAME (pid $PID) is running..."
        ;;
        1|2)
        echo "$NAME is stopped"
        RET_VAL=1
        ;;
    esac
}

do_start() {
    if check_running; then
        echo "$NAME (pid $PID) is already running..."
        return 0
    fi
    $DAEMON -u -c $CONF 2>&1 > /dev/null &
    PID=$!
    echo $PID > $PID_FILE
    sleep 0.3
    if check_running; then
        echo "Starting $NAME success"
    else
        echo "Starting $NAME failed"
        RET_VAL=1
    fi
}

do_stop() {
    if check_running; then
        kill -9 $PID
        rm -f $PID_FILE
        echo "Stopping $NAME success"
    else
        echo "$NAME is stopped"
        RET_VAL=1
    fi
}

do_restart() {
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RET_VAL=1
    ;;
esac

exit $RET_VAL


================================================
FILE: shadowsocks-go-debian
================================================
#!/bin/bash

### BEGIN INIT INFO
# Provides:          Shadowsocks-go
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the Shadowsocks-go server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

NAME=Shadowsocks-go
DAEMON=/usr/bin/shadowsocks-server
if [ -f /etc/shadowsocks-go/config.json ]; then
    CONF=/etc/shadowsocks-go/config.json
elif [ -f /etc/shadowsocks/config.json ]; then
    CONF=/etc/shadowsocks/config.json
fi
PID_DIR=/var/run
PID_FILE=$PID_DIR/shadowsocks-go.pid
RET_VAL=0

[ -x $DAEMON ] || exit 0

if [ ! -d $PID_DIR ]; then
    mkdir -p $PID_DIR
    if [ $? -ne 0 ]; then
        echo "Creating PID directory $PID_DIR failed"
        exit 1
    fi
fi

if [ ! -f $CONF ]; then
    echo "$NAME config file $CONF not found"
    exit 1
fi

check_running() {
    if [ -r $PID_FILE ]; then
        read PID < $PID_FILE
        if [ -d "/proc/$PID" ]; then
            return 0
        else
            rm -f $PID_FILE
            return 1
        fi
    else
        return 2
    fi
}

do_status() {
    check_running
    case $? in
        0)
        echo "$NAME (pid $PID) is running..."
        ;;
        1|2)
        echo "$NAME is stopped"
        RET_VAL=1
        ;;
    esac
}

do_start() {
    if check_running; then
        echo "$NAME (pid $PID) is already running..."
        return 0
    fi
    $DAEMON -u -c $CONF 2>&1 > /dev/null &
    PID=$!
    echo $PID > $PID_FILE
    sleep 0.3
    if check_running; then
        echo "Starting $NAME success"
    else
        echo "Starting $NAME failed"
        RET_VAL=1
    fi
}

do_stop() {
    if check_running; then
        kill -9 $PID
        rm -f $PID_FILE
        echo "Stopping $NAME success"
    else
        echo "$NAME is stopped"
        RET_VAL=1
    fi
}

do_restart() {
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RET_VAL=1
    ;;
esac

exit $RET_VAL


================================================
FILE: shadowsocks-go.sh
================================================
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#=================================================================#
#   System Required:  CentOS, Debian, Ubuntu                      #
#   Description: One click Install Shadowsocks-go server          #
#   Author: Teddysun <i@teddysun.com>                             #
#   Thanks: @cyfdecyf <https://twitter.com/cyfdecyf>              #
#   Intro:  https://teddysun.com/392.html                         #
#==================================================================

clear
echo
echo "#############################################################"
echo "# One click Install Shadowsocks-go server                   #"
echo "# Intro: https://teddysun.com/392.html                      #"
echo "# Author: Teddysun <i@teddysun.com>                         #"
echo "# Github: https://github.com/shadowsocks/shadowsocks-go     #"
echo "#############################################################"
echo

# Current folder
cur_dir=`pwd`
# Stream Ciphers
ciphers=(
aes-256-cfb
aes-192-cfb
aes-128-cfb
aes-256-ctr
aes-192-ctr
aes-128-ctr
chacha20-ietf
chacha20
salsa20
rc4-md5
)
# Color
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

# Make sure only root can run our script
[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1

#Check system
check_sys(){
    local checkType=$1
    local value=$2

    local release=''
    local systemPackage=''

    if [[ -f /etc/redhat-release ]]; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian" /etc/issue; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /etc/issue; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /etc/issue; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /proc/version; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /proc/version; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /proc/version; then
        release="centos"
        systemPackage="yum"
    fi

    if [[ "${checkType}" == "sysRelease" ]]; then
        if [ "${value}" == "${release}" ]; then
            return 0
        else
            return 1
        fi
    elif [[ "${checkType}" == "packageManager" ]]; then
        if [ "${value}" == "${systemPackage}" ]; then
            return 0
        else
            return 1
        fi
    fi
}

# Get version
getversion(){
    if [[ -s /etc/redhat-release ]]; then
        grep -oE  "[0-9.]+" /etc/redhat-release
    else
        grep -oE  "[0-9.]+" /etc/issue
    fi
}

# CentOS version
centosversion(){
    if check_sys sysRelease centos; then
        local code=$1
        local version="$(getversion)"
        local main_ver=${version%%.*}
        if [ "$main_ver" == "$code" ]; then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

# is 64bit or not
is_64bit(){
    if [ `getconf WORD_BIT` = '32' ] && [ `getconf LONG_BIT` = '64' ] ; then
        return 0
    else
        return 1
    fi
}

# Disable selinux
disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}

get_ip(){
    local IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip )
    [ ! -z ${IP} ] && echo ${IP} || echo
}

get_char(){
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}

# Pre-installation settings
pre_install(){
    if ! check_sys packageManager yum && ! check_sys packageManager apt; then
        echo -e "$[{red}Error${plain}] Your OS is not supported. please change OS to CentOS/Debian/Ubuntu and try again."
        exit 1
    fi
    # Set shadowsocks-go config password
    echo "Please enter password for shadowsocks-go:"
    read -p "(Default password: teddysun.com):" shadowsockspwd
    [ -z "${shadowsockspwd}" ] && shadowsockspwd="teddysun.com"
    echo
    echo "---------------------------"
    echo "password = ${shadowsockspwd}"
    echo "---------------------------"
    echo
    # Set shadowsocks-go config port
    while true
    do
    dport=$(shuf -i 9000-19999 -n 1)
    echo -e "Please enter a port for shadowsocks-go [1-65535]"
    read -p "(Default port: ${dport}):" shadowsocksport
    [ -z "${shadowsocksport}" ] && shadowsocksport=${dport}
    expr ${shadowsocksport} + 1 &>/dev/null
    if [ $? -eq 0 ]; then
        if [ ${shadowsocksport} -ge 1 ] && [ ${shadowsocksport} -le 65535 ] && [ ${shadowsocksport:0:1} != 0 ]; then
            echo
            echo "---------------------------"
            echo "port = ${shadowsocksport}"
            echo "---------------------------"
            echo
            break
        fi
    fi
    echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]"
    done

    # Set shadowsocks config stream ciphers
    while true
    do
    echo -e "Please select stream cipher for shadowsocks-go:"
    for ((i=1;i<=${#ciphers[@]};i++ )); do
        hint="${ciphers[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -p "Which cipher you'd select(Default: ${ciphers[0]}):" pick
    [ -z "$pick" ] && pick=1
    expr ${pick} + 1 &>/dev/null
    if [ $? -ne 0 ]; then
        echo -e "[${red}Error${plain}] Please enter a number"
        continue
    fi
    if [[ "$pick" -lt 1 || "$pick" -gt ${#ciphers[@]} ]]; then
        echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#ciphers[@]}"
        continue
    fi
    shadowsockscipher=${ciphers[$pick-1]}
    echo
    echo "---------------------------"
    echo "cipher = ${shadowsockscipher}"
    echo "---------------------------"
    echo
    break
    done

    echo
    echo "Press any key to start...or Press Ctrl+C to cancel"
    char=`get_char`
    #Install necessary dependencies
    if check_sys packageManager yum; then
        yum install -y wget unzip gzip curl nss
    elif check_sys packageManager apt; then
        apt-get -y update
        apt-get install -y wget unzip gzip curl libnss3
    fi
    echo

}

# Download shadowsocks-go
download_files(){
    cd ${cur_dir}
    if is_64bit; then
        if ! wget --no-check-certificate -c https://dl.lamp.sh/shadowsocks/shadowsocks-server-linux64-1.2.2.gz; then
            echo -e "[${red}Error${plain}] Failed to download shadowsocks-server-linux64-1.2.2.gz"
            exit 1
        fi
        gzip -d shadowsocks-server-linux64-1.2.2.gz
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] Decompress shadowsocks-server-linux64-1.2.2.gz failed"
            exit 1
        fi
        mv -f shadowsocks-server-linux64-1.2.2 /usr/bin/shadowsocks-server
    else
        if ! wget --no-check-certificate -c https://dl.lamp.sh/shadowsocks/shadowsocks-server-linux32-1.2.2.gz; then
            echo -e "[${red}Error${plain}] Failed to download shadowsocks-server-linux32-1.2.2.gz"
            exit 1
        fi
        gzip -d shadowsocks-server-linux32-1.2.2.gz
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] Decompress shadowsocks-server-linux32-1.2.2.gz failed"
            exit 1
        fi
        mv -f shadowsocks-server-linux32-1.2.2 /usr/bin/shadowsocks-server
    fi

    # Download start script
    if check_sys packageManager yum; then
        if ! wget --no-check-certificate -O /etc/init.d/shadowsocks https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-go; then
            echo -e "[${red}Error${plain}] Failed to download shadowsocks-go auto start script!"
            exit 1
        fi
    elif check_sys packageManager apt; then
        if ! wget --no-check-certificate -O /etc/init.d/shadowsocks https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-go-debian; then
            echo -e "[${red}Error${plain}] Failed to download shadowsocks-go auto start script!"
            exit 1
        fi
    fi
}

# Config shadowsocks
config_shadowsocks(){
    if [ ! -d /etc/shadowsocks ]; then
        mkdir -p /etc/shadowsocks
    fi
    cat > /etc/shadowsocks/config.json<<-EOF
{
    "server":"0.0.0.0",
    "server_port":${shadowsocksport},
    "local_port":1080,
    "password":"${shadowsockspwd}",
    "method":"${shadowsockscipher}",
    "timeout":300
}
EOF
}

# Firewall set
firewall_set(){
    echo -e "[${green}Info${plain}] firewall set start..."
    if centosversion 6; then
        /etc/init.d/iptables status > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            iptables -L -n | grep -i ${shadowsocksport} > /dev/null 2>&1
            if [ $? -ne 0 ]; then
                iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport ${shadowsocksport} -j ACCEPT
                iptables -I INPUT -m state --state NEW -m udp -p udp --dport ${shadowsocksport} -j ACCEPT
                /etc/init.d/iptables save
                /etc/init.d/iptables restart
            else
                echo -e "[${green}Info${plain}] port ${shadowsocksport} has been set up."
            fi
        else
            echo -e "[${yellow}Warning${plain}] iptables looks like shutdown or not installed, please manually set it if necessary."
        fi
    elif centosversion 7; then
        systemctl status firewalld > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            default_zone=$(firewall-cmd --get-default-zone)
            firewall-cmd --permanent --zone=${default_zone} --add-port=${shadowsocksport}/tcp
            firewall-cmd --permanent --zone=${default_zone} --add-port=${shadowsocksport}/udp
            firewall-cmd --reload
        else
            echo -e "[${yellow}Warning${plain}] firewalld looks like not running or not installed, please enable port ${shadowsocksport} manually if necessary."
        fi
    fi
    echo -e "[${green}Info${plain}] firewall set completed..."
}

# Install Shadowsocks-go
install(){

    if [ -f /usr/bin/shadowsocks-server ]; then
        echo "Shadowsocks-go server install success!"
        chmod +x /usr/bin/shadowsocks-server
        chmod +x /etc/init.d/shadowsocks

        if check_sys packageManager yum; then
            chkconfig --add shadowsocks
            chkconfig shadowsocks on
        elif check_sys packageManager apt; then
            update-rc.d -f shadowsocks defaults
        fi

        /etc/init.d/shadowsocks start
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] Shadowsocks-go server start failed!"
        fi
    else
        echo
        echo -e "[${red}Error${plain}] Shadowsocks-go server install failed!"
        exit 1
    fi

    clear
    echo
    echo -e "Congratulations, Shadowsocks-go server install completed!"
    echo -e "Your Server IP        : \033[41;37m $(get_ip) \033[0m"
    echo -e "Your Server Port      : \033[41;37m ${shadowsocksport} \033[0m"
    echo -e "Your Password         : \033[41;37m ${shadowsockspwd} \033[0m"
    echo -e "Your Encryption Method: \033[41;37m ${shadowsockscipher} \033[0m"
    echo
    echo "Welcome to visit:https://teddysun.com/392.html"
    echo "Enjoy it!"
    echo
}

# Uninstall Shadowsocks-go
uninstall_shadowsocks_go(){
    printf "Are you sure uninstall shadowsocks-go? (y/n) "
    printf "\n"
    read -p "(Default: n):" answer
    [ -z ${answer} ] && answer="n"
    if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then
        ps -ef | grep -v grep | grep -i "shadowsocks-server" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            /etc/init.d/shadowsocks stop
        fi
        if check_sys packageManager yum; then
            chkconfig --del shadowsocks
        elif check_sys packageManager apt; then
            update-rc.d -f shadowsocks remove
        fi
        # delete config file
        rm -rf /etc/shadowsocks
        # delete shadowsocks
        rm -f /etc/init.d/shadowsocks
        rm -f /usr/bin/shadowsocks-server
        echo "Shadowsocks-go uninstall success!"
    else
        echo
        echo "Uninstall cancelled, nothing to do..."
        echo
    fi
}

# Install Shadowsocks-go
install_shadowsocks_go(){
    disable_selinux
    pre_install
    download_files
    config_shadowsocks
    if check_sys packageManager yum; then
        firewall_set
    fi
    install
}

# Initialization step
action=$1
[ -z $1 ] && action=install
case "$action" in
    install|uninstall)
        ${action}_shadowsocks_go
        ;;
    *)
        echo "Arguments error! [${action}]"
        echo "Usage: `basename $0` [install|uninstall]"
        ;;
esac


================================================
FILE: shadowsocks-libev
================================================
#!/usr/bin/env bash
# chkconfig: 2345 90 10
# description: A secure socks5 proxy, designed to protect your Internet traffic.

### BEGIN INIT INFO
# Provides:          Shadowsocks-libev
# Required-Start:    $network $syslog
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the Shadowsocks-libev server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>
if [ -f /usr/local/bin/ss-server ]; then
    DAEMON=/usr/local/bin/ss-server
elif [ -f /usr/bin/ss-server ]; then
    DAEMON=/usr/bin/ss-server
fi
NAME=Shadowsocks-libev
CONF=/etc/shadowsocks-libev/config.json
PID_DIR=/var/run
PID_FILE=$PID_DIR/shadowsocks-libev.pid
RET_VAL=0

[ -x $DAEMON ] || exit 0

if [ ! -d $PID_DIR ]; then
    mkdir -p $PID_DIR
    if [ $? -ne 0 ]; then
        echo "Creating PID directory $PID_DIR failed"
        exit 1
    fi
fi

if [ ! -f $CONF ]; then
    echo "$NAME config file $CONF not found"
     exit 1
fi

check_running() {
    if [ -r $PID_FILE ]; then
        read PID < $PID_FILE
        if [ -d "/proc/$PID" ]; then
            return 0
        else
            rm -f $PID_FILE
            return 1
        fi
    else
        return 2
    fi
}

do_status() {
    check_running
    case $? in
        0)
        echo "$NAME (pid $PID) is running..."
        ;;
        1|2)
        echo "$NAME is stopped"
        RET_VAL=1
        ;;
    esac
}

do_start() {
    if check_running; then
        echo "$NAME (pid $PID) is already running..."
        return 0
    fi
    $DAEMON -v -c $CONF -f $PID_FILE
    if check_running; then
        echo "Starting $NAME success"
    else
        echo "Starting $NAME failed"
        RET_VAL=1
    fi
}

do_stop() {
    if check_running; then
        kill -9 $PID
        rm -f $PID_FILE
        echo "Stopping $NAME success"
    else
        echo "$NAME is stopped"
        RET_VAL=1
    fi
}

do_restart() {
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RET_VAL=1
    ;;
esac

exit $RET_VAL


================================================
FILE: shadowsocks-libev-debian
================================================
#!/usr/bin/env bash

### BEGIN INIT INFO
# Provides:          Shadowsocks-libev
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the Shadowsocks-libev server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

if [ -f /usr/local/bin/ss-server ]; then
    DAEMON=/usr/local/bin/ss-server
elif [ -f /usr/bin/ss-server ]; then
    DAEMON=/usr/bin/ss-server
fi
NAME=Shadowsocks-libev
CONF=/etc/shadowsocks-libev/config.json
PID_DIR=/var/run
PID_FILE=$PID_DIR/shadowsocks-libev.pid
RET_VAL=0

[ -x $DAEMON ] || exit 0

if [ ! -d $PID_DIR ]; then
    mkdir -p $PID_DIR
    if [ $? -ne 0 ]; then
        echo "Creating PID directory $PID_DIR failed"
        exit 1
    fi
fi

if [ ! -f $CONF ]; then
    echo "$NAME config file $CONF not found"
    exit 1
fi

check_running() {
    if [ -r $PID_FILE ]; then
        read PID < $PID_FILE
        if [ -d "/proc/$PID" ]; then
            return 0
        else
            rm -f $PID_FILE
            return 1
        fi
    else
        return 2
    fi
}

do_status() {
    check_running
    case $? in
        0)
        echo "$NAME (pid $PID) is running..."
        ;;
        1|2)
        echo "$NAME is stopped"
        RET_VAL=1
        ;;
    esac
}

do_start() {
    if check_running; then
        echo "$NAME (pid $PID) is already running..."
        return 0
    fi
    $DAEMON -v -c $CONF -f $PID_FILE
    if check_running; then
        echo "Starting $NAME success"
    else
        echo "Starting $NAME failed"
        RET_VAL=1
    fi
}

do_stop() {
    if check_running; then
        kill -9 $PID
        rm -f $PID_FILE
        echo "Stopping $NAME success"
    else
        echo "$NAME is stopped"
        RET_VAL=1
    fi
}

do_restart() {
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RET_VAL=1
    ;;
esac

exit $RET_VAL


================================================
FILE: shadowsocks-libev-debian.sh
================================================
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#===================================================================#
#   System Required:  Debian or Ubuntu                              #
#   Description: Install Shadowsocks-libev server for Debian/Ubuntu #
#   Author: Teddysun <i@teddysun.com>                               #
#   Thanks: @madeye <https://github.com/madeye>                     #
#   Intro:  https://teddysun.com/358.html                           #
#===================================================================#

# Current folder
cur_dir=$(pwd)

libsodium_file='libsodium-1.0.18'
libsodium_url='https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz'

mbedtls_file='mbedtls-2.16.12'
mbedtls_url='https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v2.16.12.tar.gz'

# Stream Ciphers
ciphers=(
aes-256-gcm
aes-192-gcm
aes-128-gcm
aes-256-ctr
aes-192-ctr
aes-128-ctr
aes-256-cfb
aes-192-cfb
aes-128-cfb
camellia-128-cfb
camellia-192-cfb
camellia-256-cfb
xchacha20-ietf-poly1305
chacha20-ietf-poly1305
chacha20-ietf
chacha20
salsa20
rc4-md5
)
# Color
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

# Make sure only root can run our script
[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1

# Disable selinux
disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}

get_ip(){
    local IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
    [ -z "${IP}" ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
    [ -z "${IP}" ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip )
    [ ! -z "${IP}" ] && echo "${IP}" || echo
}

get_ipv6(){
    local ipv6=$(wget -qO- -t1 -T2 ipv6.icanhazip.com)
    if [ -z "${ipv6}" ]; then
        return 1
    else
        return 0
    fi
}

get_char(){
    SAVEDSTTY=$(stty -g)
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty "$SAVEDSTTY"
}

get_latest_version(){
    ver=$(wget --no-check-certificate -qO- https://api.github.com/repos/shadowsocks/shadowsocks-libev/releases/latest | grep 'tag_name' | cut -d\" -f4)
    [ -z "${ver}" ] && echo "Error: Get shadowsocks-libev latest version failed" && exit 1
    shadowsocks_libev_ver="shadowsocks-libev-$(echo "${ver}" | sed -e 's/^[a-zA-Z]//g')"
    download_link="https://github.com/shadowsocks/shadowsocks-libev/releases/download/${ver}/${shadowsocks_libev_ver}.tar.gz"
    init_script_link="https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-libev-debian"
}

get_opsy(){
    [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
    [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
    [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}

check_installed(){
    if [ "$(command -v "$1")" ]; then
        return 0
    else
        return 1
    fi
}

check_version(){
    check_installed "ss-server"
    if [ $? -eq 0 ]; then
        installed_ver=$(ss-server -h | grep shadowsocks-libev | cut -d' ' -f2)
        get_latest_version
        latest_ver=$(echo "${ver}" | sed -e 's/^[a-zA-Z]//g')
        if [ "${latest_ver}" == "${installed_ver}" ]; then
            return 0
        else
            return 1
        fi
    else
        return 2
    fi
}

print_info(){
    clear
    echo "#############################################################"
    echo "# Install Shadowsocks-libev server for Debian or Ubuntu     #"
    echo "# Intro:  https://teddysun.com/358.html                     #"
    echo "# Author: Teddysun <i@teddysun.com>                         #"
    echo "# Github: https://github.com/shadowsocks/shadowsocks-libev  #"
    echo "#############################################################"
    echo
}

# Check system
check_sys(){
    local checkType=$1
    local value=$2

    local release=''
    local systemPackage=''

    if [[ -f /etc/redhat-release ]]; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /etc/issue; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /etc/issue; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /etc/issue; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /proc/version; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /proc/version; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /proc/version; then
        release="centos"
        systemPackage="yum"
    fi

    if [[ "${checkType}" == "sysRelease" ]]; then
        if [ "${value}" == "${release}" ]; then
            return 0
        else
            return 1
        fi
    elif [[ "${checkType}" == "packageManager" ]]; then
        if [ "${value}" == "${systemPackage}" ]; then
            return 0
        else
            return 1
        fi
    fi
}

version_gt(){
    test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"
}

check_kernel_version(){
    local kernel_version=$(uname -r | cut -d- -f1)
    if version_gt "${kernel_version}" 3.7.0; then
        return 0
    else
        return 1
    fi
}

check_kernel_headers(){
    if check_sys packageManager yum; then
        if rpm -qa | grep -q headers-$(uname -r); then
            return 0
        else
            return 1
        fi
    elif check_sys packageManager apt; then
        if dpkg -s linux-headers-$(uname -r) > /dev/null 2>&1; then
            return 0
        else
            return 1
        fi
    fi
    return 1
}

debianversion(){
    if check_sys sysRelease debian;then
        local version=$( get_opsy )
        local code=${1}
        local main_ver=$( echo "${version}" | sed 's/[^0-9]//g')
        if [ "${main_ver}" == "${code}" ];then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

# Pre-installation settings
pre_install(){
    # Check OS system
    if ! check_sys packageManager apt; then
        echo -e "[${red}Error${plain}] Your OS is not supported to run it, please change OS to Debian/Ubuntu and try again."
        exit 1
    fi

    # Check version
    check_version
    status=$?
    if [ ${status} -eq 0 ]; then
        echo -e "[${green}Info${plain}] Latest version ${green}${shadowsocks_libev_ver}${plain} has already been installed, nothing to do..."
        exit 0
    elif [ ${status} -eq 1 ]; then
        echo -e "Installed version: ${red}${installed_ver}${plain}"
        echo -e "Latest version: ${red}${latest_ver}${plain}"
        echo -e "[${green}Info${plain}] Upgrade shadowsocks libev to latest version..."
        ps -ef | grep -v grep | grep -i "ss-server" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            /etc/init.d/shadowsocks stop
        fi
    elif [ ${status} -eq 2 ]; then
        print_info
        get_latest_version
        echo -e "[${green}Info${plain}] Latest version: ${green}${shadowsocks_libev_ver}${plain}"
        echo
    fi

    # Set shadowsocks-libev config password
    echo "Please input password for shadowsocks-libev:"
    read -p "(Default password: teddysun.com):" shadowsockspwd
    [ -z "${shadowsockspwd}" ] && shadowsockspwd="teddysun.com"
    echo
    echo "---------------------------"
    echo "password = ${shadowsockspwd}"
    echo "---------------------------"
    echo

    # Set shadowsocks-libev config port
    while true
    do
    dport=$(shuf -i 9000-19999 -n 1)
    echo -e "Please enter a port for shadowsocks-libev [1-65535]"
    read -p "(Default port: ${dport}):" shadowsocksport
    [ -z "$shadowsocksport" ] && shadowsocksport=${dport}
    expr "${shadowsocksport}" + 1 &>/dev/null
    if [ $? -eq 0 ]; then
        if [ "${shadowsocksport}" -ge 1 ] && [ "${shadowsocksport}" -le 65535 ] && [ "${shadowsocksport:0:1}" != 0 ]; then
            echo
            echo "---------------------------"
            echo "port = ${shadowsocksport}"
            echo "---------------------------"
            echo
            break
        fi
    fi
    echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]"
    done

    # Set shadowsocks config stream ciphers
    while true
    do
    echo -e "Please select stream cipher for shadowsocks-libev:"
    for ((i=1;i<=${#ciphers[@]};i++ )); do
        hint="${ciphers[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -p "Which cipher you'd select(Default: ${ciphers[0]}):" pick
    [ -z "$pick" ] && pick=1
    expr ${pick} + 1 &>/dev/null
    if [ $? -ne 0 ]; then
        echo -e "[${red}Error${plain}] Please enter a number"
        continue
    fi
    if [[ "$pick" -lt 1 || "$pick" -gt ${#ciphers[@]} ]]; then
        echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#ciphers[@]}"
        continue
    fi
    shadowsockscipher=${ciphers[$pick-1]}
    echo
    echo "---------------------------"
    echo "cipher = ${shadowsockscipher}"
    echo "---------------------------"
    echo
    break
    done

    echo
    echo "Press any key to start...or press Ctrl+C to cancel"
    char=$(get_char)

    # Update System
    apt-get -y update
    # Install necessary dependencies
    apt-get -y --no-install-recommends install gettext build-essential autoconf automake libtool openssl libssl-dev zlib1g-dev libpcre3-dev libev-dev libc-ares-dev
}

download() {
    local filename=${1}
    local cur_dir=$(pwd)
    if [ -s "${filename}" ]; then
        echo -e "[${green}Info${plain}] ${filename} [found]"
    else
        echo -e "[${green}Info${plain}] ${filename} not found, download now..."
        wget --no-check-certificate -cq -t3 -T60 -O "${1}" "${2}"
        if [ $? -eq 0 ]; then
            echo -e "[${green}Info${plain}] ${filename} download completed..."
        else
            echo -e "[${red}Error${plain}] Failed to download ${filename}, please download it to ${cur_dir} directory manually and try again."
            exit 1
        fi
    fi
}

# Download latest shadowsocks-libev
download_files(){
    cd "${cur_dir}" || exit

    download "${shadowsocks_libev_ver}.tar.gz" "${download_link}"
    download "${libsodium_file}.tar.gz" "${libsodium_url}"
    download "${mbedtls_file}.tar.gz" "${mbedtls_url}"
    download "/etc/init.d/shadowsocks" "${init_script_link}"
}

install_libsodium() {
    if [ ! -f /usr/lib/libsodium.a ]; then
        cd "${cur_dir}" || exit
        tar zxf ${libsodium_file}.tar.gz
        cd ${libsodium_file} || exit
        ./configure --prefix=/usr && make && make install
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] ${libsodium_file} install failed."
            exit 1
        fi
    else
        echo -e "[${green}Info${plain}] ${libsodium_file} already installed."
    fi
}

install_mbedtls() {
    if [ ! -f /usr/lib/libmbedtls.a ]; then
        cd "${cur_dir}" || exit
        tar zxf "${mbedtls_file}.tar.gz"
        cd "${mbedtls_file}" || exit
        make SHARED=1 CFLAGS=-fPIC
        make DESTDIR=/usr install
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] ${mbedtls_file} install failed."
            exit 1
        fi
    else
        echo -e "[${green}Info${plain}] ${mbedtls_file} already installed."
    fi
}

# Config shadowsocks
config_shadowsocks(){
    local server_value="\"0.0.0.0\""
    if get_ipv6; then
        server_value="[\"[::0]\",\"0.0.0.0\"]"
    fi

    if [ ! -d /etc/shadowsocks-libev ]; then
        mkdir -p /etc/shadowsocks-libev
    fi
    cat > /etc/shadowsocks-libev/config.json<<-EOF
{
    "server":${server_value},
    "server_port":${shadowsocksport},
    "password":"${shadowsockspwd}",
    "timeout":300,
    "user":"nobody",
    "method":"${shadowsockscipher}",
    "fast_open":false,
    "nameserver":"1.0.0.1",
    "mode":"tcp_and_udp"
}
EOF
}

# Install Shadowsocks-libev
install_shadowsocks(){
    install_libsodium
    install_mbedtls

    ldconfig
    cd "${cur_dir}" || exit
    tar zxf "${shadowsocks_libev_ver}".tar.gz
    cd "${shadowsocks_libev_ver}" || exit
    ./configure --disable-documentation
    make && make install
    if [ $? -eq 0 ]; then
        chmod +x /etc/init.d/shadowsocks
        update-rc.d -f shadowsocks defaults
        # Start shadowsocks
        /etc/init.d/shadowsocks start
        if [ $? -eq 0 ]; then
            echo -e "[${green}Info${plain}] Shadowsocks-libev start success!"
        else
            echo -e "[${yellow}Warning${plain}] Shadowsocks-libev start failure!"
        fi
    else
        echo
        echo -e "[${red}Error${plain}] Shadowsocks-libev install failed. please visit https://teddysun.com/358.html and contact."
        exit 1
    fi

    cd "${cur_dir}" || exit
    rm -rf "${shadowsocks_libev_ver}" "${shadowsocks_libev_ver}".tar.gz
    rm -rf ${libsodium_file} ${libsodium_file}.tar.gz
    rm -rf "${mbedtls_file}" "${mbedtls_file}"-apache.tgz

    clear
    echo
    echo -e "Congratulations, Shadowsocks-libev server install completed!"
    echo -e "Your Server IP        : \033[41;37m $(get_ip) \033[0m"
    echo -e "Your Server Port      : \033[41;37m ${shadowsocksport} \033[0m"
    echo -e "Your Password         : \033[41;37m ${shadowsockspwd} \033[0m"
    echo -e "Your Encryption Method: \033[41;37m ${shadowsockscipher} \033[0m"
    echo
    echo "Welcome to visit:https://teddysun.com/358.html"
    echo "Enjoy it!"
    echo
}

# Install Shadowsocks-libev
install_shadowsocks_libev(){
    disable_selinux
    pre_install
    download_files
    config_shadowsocks
    install_shadowsocks
}

# Uninstall Shadowsocks-libev
uninstall_shadowsocks_libev(){
    clear
    print_info
    printf "Are you sure uninstall Shadowsocks-libev? (y/n)"
    printf "\n"
    read -p "(Default: n):" answer
    [ -z "${answer}" ] && answer="n"

    if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then
        ps -ef | grep -v grep | grep -i "ss-server" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            /etc/init.d/shadowsocks stop
        fi
        update-rc.d -f shadowsocks remove

        rm -fr /etc/shadowsocks-libev
        rm -f /usr/local/bin/ss-local
        rm -f /usr/local/bin/ss-tunnel
        rm -f /usr/local/bin/ss-server
        rm -f /usr/local/bin/ss-manager
        rm -f /usr/local/bin/ss-redir
        rm -f /usr/local/bin/ss-nat
        rm -f /usr/local/lib/libshadowsocks-libev.a
        rm -f /usr/local/lib/libshadowsocks-libev.la
        rm -f /usr/local/include/shadowsocks.h
        rm -f /usr/local/lib/pkgconfig/shadowsocks-libev.pc
        rm -f /usr/local/share/man/man1/ss-local.1
        rm -f /usr/local/share/man/man1/ss-tunnel.1
        rm -f /usr/local/share/man/man1/ss-server.1
        rm -f /usr/local/share/man/man1/ss-manager.1
        rm -f /usr/local/share/man/man1/ss-redir.1
        rm -f /usr/local/share/man/man1/ss-nat.1
        rm -f /usr/local/share/man/man8/shadowsocks-libev.8
        rm -fr /usr/local/share/doc/shadowsocks-libev
        rm -f /etc/init.d/shadowsocks
        echo "Shadowsocks-libev uninstall success!"
    else
        echo
        echo "uninstall cancelled, nothing to do..."
        echo
    fi
}

# Initialization step
action=$1
[ -z "$1" ] && action=install
case "$action" in
    install|uninstall)
        ${action}_shadowsocks_libev
        ;;
    *)
        echo "Arguments error! [${action}]"
        echo "Usage: $(basename "$0") [install|uninstall]"
        ;;
esac


================================================
FILE: shadowsocks-libev.sh
================================================
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#===================================================================#
#   System Required:  CentOS 6 or 7                                 #
#   Description: Install Shadowsocks-libev server for CentOS 6 or 7 #
#   Author: Teddysun <i@teddysun.com>                               #
#   Thanks: @madeye <https://github.com/madeye>                     #
#   Intro:  https://teddysun.com/357.html                           #
#===================================================================#

# Current folder
cur_dir=$(pwd)

libsodium_file='libsodium-1.0.18'
libsodium_url='https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz'

mbedtls_file='mbedtls-2.16.12'
mbedtls_url='https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v2.16.12.tar.gz'

# Stream Ciphers
ciphers=(
aes-256-gcm
aes-192-gcm
aes-128-gcm
aes-256-ctr
aes-192-ctr
aes-128-ctr
aes-256-cfb
aes-192-cfb
aes-128-cfb
camellia-128-cfb
camellia-192-cfb
camellia-256-cfb
xchacha20-ietf-poly1305
chacha20-ietf-poly1305
chacha20-ietf
chacha20
salsa20
rc4-md5
)
# Color
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

# Make sure only root can run our script
[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1

# Disable selinux
disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}

get_ip(){
    local IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
    [ -z "${IP}" ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
    [ -z "${IP}" ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip )
    [ ! -z "${IP}" ] && echo "${IP}" || echo
}

get_ipv6(){
    local ipv6=$(wget -qO- -t1 -T2 ipv6.icanhazip.com)
    if [ -z "${ipv6}" ]; then
        return 1
    else
        return 0
    fi
}

get_char(){
    SAVEDSTTY=$(stty -g)
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty "$SAVEDSTTY"
}

get_latest_version(){
    ver=$(wget --no-check-certificate -qO- https://api.github.com/repos/shadowsocks/shadowsocks-libev/releases/latest | grep 'tag_name' | cut -d\" -f4)
    [ -z "${ver}" ] && echo "Error: Get shadowsocks-libev latest version failed" && exit 1
    shadowsocks_libev_ver="shadowsocks-libev-$(echo "${ver}" | sed -e 's/^[a-zA-Z]//g')"
    download_link="https://github.com/shadowsocks/shadowsocks-libev/releases/download/${ver}/${shadowsocks_libev_ver}.tar.gz"
    init_script_link="https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-libev"
}

check_installed(){
    if [ "$(command -v "$1")" ]; then
        return 0
    else
        return 1
    fi
}

check_version(){
    check_installed "ss-server"
    if [ $? -eq 0 ]; then
        installed_ver=$(ss-server -h | grep shadowsocks-libev | cut -d' ' -f2)
        get_latest_version
        latest_ver=$(echo "${ver}" | sed -e 's/^[a-zA-Z]//g')
        if [ "${latest_ver}" == "${installed_ver}" ]; then
            return 0
        else
            return 1
        fi
    else
        return 2
    fi
}

print_info(){
    clear
    echo "#############################################################"
    echo "# Install Shadowsocks-libev server for CentOS 6 or 7        #"
    echo "# Intro:  https://teddysun.com/357.html                     #"
    echo "# Author: Teddysun <i@teddysun.com>                         #"
    echo "# Github: https://github.com/shadowsocks/shadowsocks-libev  #"
    echo "#############################################################"
    echo
}

# Check system
check_sys(){
    local checkType=$1
    local value=$2

    local release=''
    local systemPackage=''

    if [[ -f /etc/redhat-release ]]; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /etc/issue; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /etc/issue; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /etc/issue; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /proc/version; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /proc/version; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /proc/version; then
        release="centos"
        systemPackage="yum"
    fi

    if [[ "${checkType}" == "sysRelease" ]]; then
        if [ "${value}" == "${release}" ]; then
            return 0
        else
            return 1
        fi
    elif [[ "${checkType}" == "packageManager" ]]; then
        if [ "${value}" == "${systemPackage}" ]; then
            return 0
        else
            return 1
        fi
    fi
}

version_gt(){
    test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"
}

check_kernel_version(){
    local kernel_version=$(uname -r | cut -d- -f1)
    if version_gt "${kernel_version}" 3.7.0; then
        return 0
    else
        return 1
    fi
}

check_kernel_headers(){
    if check_sys packageManager yum; then
        if rpm -qa | grep -q headers-$(uname -r); then
            return 0
        else
            return 1
        fi
    elif check_sys packageManager apt; then
        if dpkg -s linux-headers-$(uname -r) > /dev/null 2>&1; then
            return 0
        else
            return 1
        fi
    fi
    return 1
}

# Get version
getversion(){
    if [[ -s /etc/redhat-release ]]; then
        grep -oE  "[0-9.]+" /etc/redhat-release
    else
        grep -oE  "[0-9.]+" /etc/issue
    fi
}

# CentOS version
centosversion(){
    if check_sys sysRelease centos; then
        local code=$1
        local version="$(getversion)"
        local main_ver=${version%%.*}
        if [ "$main_ver" == "$code" ]; then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

# Pre-installation settings
pre_install(){
    # Check OS system
    if check_sys sysRelease centos; then
        # Not support CentOS 5
        if centosversion 5; then
            echo -e "[${red}Error${plain}] Not support CentOS 5, please change to CentOS 6 or 7 and try again."
            exit 1
        fi
    else
        echo -e "[${red}Error${plain}] Your OS is not supported to run it, please change OS to CentOS and try again."
        exit 1
    fi

    # Check version
    check_version
    status=$?
    if [ ${status} -eq 0 ]; then
        echo -e "[${green}Info${plain}] Latest version ${green}${shadowsocks_libev_ver}${plain} has already been installed, nothing to do..."
        exit 0
    elif [ ${status} -eq 1 ]; then
        echo -e "Installed version: ${red}${installed_ver}${plain}"
        echo -e "Latest version: ${red}${latest_ver}${plain}"
        echo -e "[${green}Info${plain}] Upgrade shadowsocks libev to latest version..."
        ps -ef | grep -v grep | grep -i "ss-server" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            /etc/init.d/shadowsocks stop
        fi
    elif [ ${status} -eq 2 ]; then
        print_info
        get_latest_version
        echo -e "[${green}Info${plain}] Latest version: ${green}${shadowsocks_libev_ver}${plain}"
        echo
    fi

    # Set shadowsocks-libev config password
    echo "Please enter password for shadowsocks-libev:"
    read -p "(Default password: teddysun.com):" shadowsockspwd
    [ -z "${shadowsockspwd}" ] && shadowsockspwd="teddysun.com"
    echo
    echo "---------------------------"
    echo "password = ${shadowsockspwd}"
    echo "---------------------------"
    echo

    # Set shadowsocks-libev config port
    while true
    do
    dport=$(shuf -i 9000-19999 -n 1)
    echo -e "Please enter a port for shadowsocks-libev [1-65535]"
    read -p "(Default port: ${dport}):" shadowsocksport
    [ -z "$shadowsocksport" ] && shadowsocksport=${dport}
    expr "${shadowsocksport}" + 1 &>/dev/null
    if [ $? -eq 0 ]; then
        if [ "${shadowsocksport}" -ge 1 ] && [ "${shadowsocksport}" -le 65535 ] && [ "${shadowsocksport:0:1}" != 0 ]; then
            echo
            echo "---------------------------"
            echo "port = ${shadowsocksport}"
            echo "---------------------------"
            echo
            break
        fi
    fi
    echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]"
    done

    # Set shadowsocks config stream ciphers
    while true
    do
    echo -e "Please select stream cipher for shadowsocks-libev:"
    for ((i=1;i<=${#ciphers[@]};i++ )); do
        hint="${ciphers[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -p "Which cipher you'd select(Default: ${ciphers[0]}):" pick
    [ -z "$pick" ] && pick=1
    expr ${pick} + 1 &>/dev/null
    if [ $? -ne 0 ]; then
        echo -e "[${red}Error${plain}] Please enter a number"
        continue
    fi
    if [[ "$pick" -lt 1 || "$pick" -gt ${#ciphers[@]} ]]; then
        echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#ciphers[@]}"
        continue
    fi
    shadowsockscipher=${ciphers[$pick-1]}
    echo
    echo "---------------------------"
    echo "cipher = ${shadowsockscipher}"
    echo "---------------------------"
    echo
    break
    done

    echo
    echo "Press any key to start...or press Ctrl+C to cancel"
    char=$(get_char)
    #Install necessary dependencies
    echo -e "[${green}Info${plain}] Checking the EPEL repository..."
    if [ ! -f /etc/yum.repos.d/epel.repo ]; then
        yum install -y -q epel-release
    fi
    [ ! -f /etc/yum.repos.d/epel.repo ] && echo -e "[${red}Error${plain}] Install EPEL repository failed, please check it." && exit 1
    [ ! "$(command -v yum-config-manager)" ] && yum install -y -q yum-utils
    if [ x"$(yum-config-manager epel | grep -w enabled | awk '{print $3}')" != x"True" ]; then
        yum-config-manager --enable epel
    fi
    echo -e "[${green}Info${plain}] Checking the EPEL repository complete..."
    yum install -y -q unzip openssl openssl-devel gettext gcc autoconf libtool automake make asciidoc xmlto libev-devel pcre pcre-devel git c-ares-devel
}

download() {
    local filename=${1}
    local cur_dir=$(pwd)
    if [ -s "${filename}" ]; then
        echo -e "[${green}Info${plain}] ${filename} [found]"
    else
        echo -e "[${green}Info${plain}] ${filename} not found, download now..."
        wget --no-check-certificate -cq -t3 -T60 -O "${1}" "${2}"
        if [ $? -eq 0 ]; then
            echo -e "[${green}Info${plain}] ${filename} download completed..."
        else
            echo -e "[${red}Error${plain}] Failed to download ${filename}, please download it to ${cur_dir} directory manually and try again."
            exit 1
        fi
    fi
}

# Download latest shadowsocks-libev
download_files(){
    cd "${cur_dir}" || exit

    download "${shadowsocks_libev_ver}.tar.gz" "${download_link}"
    download "${libsodium_file}.tar.gz" "${libsodium_url}"
    download "${mbedtls_file}.tar.gz" "${mbedtls_url}"
    download "/etc/init.d/shadowsocks" "${init_script_link}"
}

install_libsodium() {
    if [ ! -f /usr/lib/libsodium.a ]; then
        cd "${cur_dir}" || exit
        tar zxf ${libsodium_file}.tar.gz
        cd ${libsodium_file} || exit
        ./configure --prefix=/usr && make && make install
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] ${libsodium_file} install failed."
            exit 1
        fi
    else
        echo -e "[${green}Info${plain}] ${libsodium_file} already installed."
    fi
}

install_mbedtls() {
    if [ ! -f /usr/lib/libmbedtls.a ]; then
        cd "${cur_dir}" || exit
        tar zxf "${mbedtls_file}.tar.gz"
        cd "${mbedtls_file}" || exit
        make SHARED=1 CFLAGS=-fPIC
        make DESTDIR=/usr install
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] ${mbedtls_file} install failed."
            exit 1
        fi
    else
        echo -e "[${green}Info${plain}] ${mbedtls_file} already installed."
    fi
}

# Config shadowsocks
config_shadowsocks(){
    local server_value="\"0.0.0.0\""
    if get_ipv6; then
        server_value="[\"[::0]\",\"0.0.0.0\"]"
    fi

    if [ ! -d /etc/shadowsocks-libev ]; then
        mkdir -p /etc/shadowsocks-libev
    fi
    cat > /etc/shadowsocks-libev/config.json<<-EOF
{
    "server":${server_value},
    "server_port":${shadowsocksport},
    "password":"${shadowsockspwd}",
    "timeout":300,
    "user":"nobody",
    "method":"${shadowsockscipher}",
    "fast_open":false,
    "nameserver":"1.0.0.1",
    "mode":"tcp_and_udp"
}
EOF
}

# Firewall set
firewall_set(){
    echo -e "[${green}Info${plain}] firewall set start..."
    if centosversion 6; then
        /etc/init.d/iptables status > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            iptables -L -n | grep -i "${shadowsocksport}" > /dev/null 2>&1
            if [ $? -ne 0 ]; then
                iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport "${shadowsocksport}" -j ACCEPT
                iptables -I INPUT -m state --state NEW -m udp -p udp --dport "${shadowsocksport}" -j ACCEPT
                /etc/init.d/iptables save
                /etc/init.d/iptables restart
            else
                echo -e "[${green}Info${plain}] port ${shadowsocksport} has been set up."
            fi
        else
            echo -e "[${yellow}Warning${plain}] iptables looks like shutdown or not installed, please manually set it if necessary."
        fi
    elif centosversion 7; then
        systemctl status firewalld > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            default_zone=$(firewall-cmd --get-default-zone)
            firewall-cmd --permanent --zone="${default_zone}" --add-port="${shadowsocksport}"/tcp
            firewall-cmd --permanent --zone="${default_zone}" --add-port="${shadowsocksport}"/udp
            firewall-cmd --reload
        else
            echo -e "[${yellow}Warning${plain}] firewalld looks like not running or not installed, please enable port ${shadowsocksport} manually if necessary."
        fi
    fi
    echo -e "[${green}Info${plain}] firewall set completed..."
}

# Install Shadowsocks-libev
install_shadowsocks(){
    install_libsodium
    install_mbedtls

    ldconfig
    cd "${cur_dir}" || exit
    tar zxf "${shadowsocks_libev_ver}".tar.gz
    cd "${shadowsocks_libev_ver}" || exit
    ./configure --disable-documentation
    make && make install
    if [ $? -eq 0 ]; then
        chmod +x /etc/init.d/shadowsocks
        chkconfig --add shadowsocks
        chkconfig shadowsocks on
        # Start shadowsocks
        /etc/init.d/shadowsocks start
        if [ $? -eq 0 ]; then
            echo -e "[${green}Info${plain}] Shadowsocks-libev start success!"
        else
            echo -e "[${yellow}Warning${plain}] Shadowsocks-libev start failure!"
        fi
    else
        echo
        echo -e "[${red}Error${plain}] Shadowsocks-libev install failed. please visit https://teddysun.com/357.html and contact."
        exit 1
    fi

    cd "${cur_dir}" || exit
    rm -rf "${shadowsocks_libev_ver}" "${shadowsocks_libev_ver}".tar.gz
    rm -rf ${libsodium_file} ${libsodium_file}.tar.gz
    rm -rf "${mbedtls_file}" "${mbedtls_file}"-apache.tgz

    clear
    echo
    echo -e "Congratulations, Shadowsocks-libev server install completed!"
    echo -e "Your Server IP        : \033[41;37m $(get_ip) \033[0m"
    echo -e "Your Server Port      : \033[41;37m ${shadowsocksport} \033[0m"
    echo -e "Your Password         : \033[41;37m ${shadowsockspwd} \033[0m"
    echo -e "Your Encryption Method: \033[41;37m ${shadowsockscipher} \033[0m"
    echo
    echo "Welcome to visit:https://teddysun.com/357.html"
    echo "Enjoy it!"
    echo
}

# Install Shadowsocks-libev
install_shadowsocks_libev(){
    disable_selinux
    pre_install
    download_files
    config_shadowsocks
    firewall_set
    install_shadowsocks
}

# Uninstall Shadowsocks-libev
uninstall_shadowsocks_libev(){
    clear
    print_info
    printf "Are you sure uninstall Shadowsocks-libev? (y/n)"
    printf "\n"
    read -p "(Default: n):" answer
    [ -z "${answer}" ] && answer="n"

    if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then
        ps -ef | grep -v grep | grep -i "ss-server" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            /etc/init.d/shadowsocks stop
        fi
        chkconfig --del shadowsocks
        rm -fr /etc/shadowsocks-libev
        rm -f /usr/local/bin/ss-local
        rm -f /usr/local/bin/ss-tunnel
        rm -f /usr/local/bin/ss-server
        rm -f /usr/local/bin/ss-manager
        rm -f /usr/local/bin/ss-redir
        rm -f /usr/local/bin/ss-nat
        rm -f /usr/local/lib/libshadowsocks-libev.a
        rm -f /usr/local/lib/libshadowsocks-libev.la
        rm -f /usr/local/include/shadowsocks.h
        rm -f /usr/local/lib/pkgconfig/shadowsocks-libev.pc
        rm -f /usr/local/share/man/man1/ss-local.1
        rm -f /usr/local/share/man/man1/ss-tunnel.1
        rm -f /usr/local/share/man/man1/ss-server.1
        rm -f /usr/local/share/man/man1/ss-manager.1
        rm -f /usr/local/share/man/man1/ss-redir.1
        rm -f /usr/local/share/man/man1/ss-nat.1
        rm -f /usr/local/share/man/man8/shadowsocks-libev.8
        rm -fr /usr/local/share/doc/shadowsocks-libev
        rm -f /etc/init.d/shadowsocks
        echo "Shadowsocks-libev uninstall success!"
    else
        echo
        echo "uninstall cancelled, nothing to do..."
        echo
    fi
}

# Initialization step
action=$1
[ -z "$1" ] && action=install
case "$action" in
    install|uninstall)
        ${action}_shadowsocks_libev
        ;;
    *)
        echo "Arguments error! [${action}]"
        echo "Usage: $(basename "$0") [install|uninstall]"
        ;;
esac


================================================
FILE: shadowsocks-manager
================================================
#!/usr/bin/env bash
# chkconfig: 2345 90 10
# description: A secure socks5 proxy, designed to protect your Internet traffic.

### BEGIN INIT INFO
# Provides:          Shadowsocks-libev
# Required-Start:    $network $syslog
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or Stop the Shadowsocks-libev server to support multiple users with ss-manager
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

if [ -f /usr/local/bin/ss-manager ]; then
    MANAGER=/usr/local/bin/ss-manager
elif [ -f /usr/bin/ss-manager ]; then
    MANAGER=/usr/bin/ss-manager
fi

if [ -f /usr/local/bin/ss-server ]; then
    DAEMON=/usr/local/bin/ss-server
elif [ -f /usr/bin/ss-server ]; then
    DAEMON=/usr/bin/ss-server
fi

NAME=Shadowsocks-manager
CONF=/etc/shadowsocks-manager/config.json
PID_DIR=/var/run
PID_FILE=$PID_DIR/shadowsocks-manager.pid
SOCK_FILE=$PID_DIR/shadowsocks-manager.sock
WK_DIR=~/.shadowsocks
WK_PID_LST=($WK_DIR/.*pid)

RET_VAL=0

[ -x $MANAGER ] || exit 0
[ -x $DAEMON ] || exit 0

if [ ! -d $PID_DIR ]; then
    mkdir -p $PID_DIR
    if [ $? -ne 0 ]; then
        echo "Creating PID directory $PID_DIR failed"
        exit 1
    fi
fi

if [ ! -f $CONF ]; then
    echo "$NAME config file $CONF not found"
    exit 1
fi

check_running() {
    if [ -r $PID_FILE ]; then
        read PID < $PID_FILE
        if [ -d "/proc/$PID" ]; then
            return 0
        else
            rm -f $PID_FILE
            return 1
        fi
    else
        return 2
    fi
}

do_status() {
    check_running
    case $? in
        0)
        echo "$NAME (pid $PID) is running..."
        ;;
        1|2)
        echo "$NAME is stopped"
        RET_VAL=1
        ;;
    esac
}

do_start() {
    if check_running; then
        echo "$NAME (pid $PID) is already running..."
        return 0
    fi
    $MANAGER --manager-address $SOCK_FILE --executable $DAEMON -c $CONF -f $PID_FILE
    if check_running; then
        echo "Starting $NAME success"
    else
        echo "Starting $NAME failed"
        RET_VAL=1
    fi
}

do_stop() {
    if check_running; then
        kill -9 $PID
        rm -f $PID_FILE
        rm -f $SOCK_FILE
        for i in "${WK_PID_LST[@]}"; do
            [ -r $i ] && read WK_PID < $i
            [ -d "/proc/$WK_PID" ] && kill -9 $WK_PID
            rm -f $i
        done
        echo "Stopping $NAME success"
    else
        echo "$NAME is stopped"
        RET_VAL=1
    fi
}

do_restart() {
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RET_VAL=1
    ;;
esac

exit $RET_VAL


================================================
FILE: shadowsocks.sh
================================================
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#=================================================================#
#   System Required:  CentOS 6+, Debian 7+, Ubuntu 12+            #
#   Description: One click Install Shadowsocks-Python server      #
#   Author: Teddysun <i@teddysun.com>                             #
#   Thanks: @clowwindy <https://twitter.com/clowwindy>            #
#   Intro:  https://teddysun.com/342.html                         #
#=================================================================#

clear
echo
echo "#############################################################"
echo "# One click Install Shadowsocks-Python server               #"
echo "# Intro: https://teddysun.com/342.html                      #"
echo "# Author: Teddysun <i@teddysun.com>                         #"
echo "# Github: https://github.com/shadowsocks/shadowsocks        #"
echo "#############################################################"
echo

libsodium_file="libsodium-1.0.18"
libsodium_url="https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz"

# Current folder
cur_dir=`pwd`
# Stream Ciphers
ciphers=(
aes-256-gcm
aes-192-gcm
aes-128-gcm
aes-256-ctr
aes-192-ctr
aes-128-ctr
aes-256-cfb
aes-192-cfb
aes-128-cfb
camellia-128-cfb
camellia-192-cfb
camellia-256-cfb
chacha20-ietf-poly1305
chacha20-ietf
chacha20
rc4-md5
)
# Color
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

# Make sure only root can run our script
[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1

# Disable selinux
disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}

#Check system
check_sys(){
    local checkType=$1
    local value=$2

    local release=''
    local systemPackage=''

    if [[ -f /etc/redhat-release ]]; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /etc/issue; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /etc/issue; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /etc/issue; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /proc/version; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /proc/version; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /proc/version; then
        release="centos"
        systemPackage="yum"
    fi

    if [[ "${checkType}" == "sysRelease" ]]; then
        if [ "${value}" == "${release}" ]; then
            return 0
        else
            return 1
        fi
    elif [[ "${checkType}" == "packageManager" ]]; then
        if [ "${value}" == "${systemPackage}" ]; then
            return 0
        else
            return 1
        fi
    fi
}

# Get version
getversion(){
    if [[ -s /etc/redhat-release ]]; then
        grep -oE  "[0-9.]+" /etc/redhat-release
    else
        grep -oE  "[0-9.]+" /etc/issue
    fi
}

# CentOS version
centosversion(){
    if check_sys sysRelease centos; then
        local code=$1
        local version="$(getversion)"
        local main_ver=${version%%.*}
        if [ "$main_ver" == "$code" ]; then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

# Get public IP address
get_ip(){
    local IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip )
    [ ! -z ${IP} ] && echo ${IP} || echo
}

get_char(){
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}

# Pre-installation settings
pre_install(){
    if check_sys packageManager yum || check_sys packageManager apt; then
        # Not support CentOS 5
        if centosversion 5; then
            echo -e "$[{red}Error${plain}] Not supported CentOS 5, please change to CentOS 6+/Debian 7+/Ubuntu 12+ and try again."
            exit 1
        fi
    else
        echo -e "[${red}Error${plain}] Your OS is not supported. please change OS to CentOS/Debian/Ubuntu and try again."
        exit 1
    fi
    # Set shadowsocks config password
    echo "Please enter password for shadowsocks-python"
    read -p "(Default password: teddysun.com):" shadowsockspwd
    [ -z "${shadowsockspwd}" ] && shadowsockspwd="teddysun.com"
    echo
    echo "---------------------------"
    echo "password = ${shadowsockspwd}"
    echo "---------------------------"
    echo
    # Set shadowsocks config port
    while true
    do
    dport=$(shuf -i 9000-19999 -n 1)
    echo "Please enter a port for shadowsocks-python [1-65535]"
    read -p "(Default port: ${dport}):" shadowsocksport
    [ -z "$shadowsocksport" ] && shadowsocksport=${dport}
    expr ${shadowsocksport} + 1 &>/dev/null
    if [ $? -eq 0 ]; then
        if [ ${shadowsocksport} -ge 1 ] && [ ${shadowsocksport} -le 65535 ] && [ ${shadowsocksport:0:1} != 0 ]; then
            echo
            echo "---------------------------"
            echo "port = ${shadowsocksport}"
            echo "---------------------------"
            echo
            break
        fi
    fi
    echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]"
    done

    # Set shadowsocks config stream ciphers
    while true
    do
    echo -e "Please select stream cipher for shadowsocks-python:"
    for ((i=1;i<=${#ciphers[@]};i++ )); do
        hint="${ciphers[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -p "Which cipher you'd select(Default: ${ciphers[0]}):" pick
    [ -z "$pick" ] && pick=1
    expr ${pick} + 1 &>/dev/null
    if [ $? -ne 0 ]; then
        echo -e "[${red}Error${plain}] Please enter a number"
        continue
    fi
    if [[ "$pick" -lt 1 || "$pick" -gt ${#ciphers[@]} ]]; then
        echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#ciphers[@]}"
        continue
    fi
    shadowsockscipher=${ciphers[$pick-1]}
    echo
    echo "---------------------------"
    echo "cipher = ${shadowsockscipher}"
    echo "---------------------------"
    echo
    break
    done

    echo
    echo "Press any key to start...or Press Ctrl+C to cancel"
    char=`get_char`
    # Install necessary dependencies
    if check_sys packageManager yum; then
        yum install -y python python-devel python-setuptools openssl openssl-devel curl wget unzip gcc automake autoconf make libtool
    elif check_sys packageManager apt; then
        apt-get -y update
        apt-get -y install python python-dev python-setuptools openssl libssl-dev curl wget unzip gcc automake autoconf make libtool
    fi
    cd ${cur_dir}
}

# Download files
download_files(){
    # Download libsodium file
    if ! wget --no-check-certificate -O ${libsodium_file}.tar.gz ${libsodium_url}; then
        echo -e "[${red}Error${plain}] Failed to download ${libsodium_file}.tar.gz!"
        exit 1
    fi
    # Download Shadowsocks file
    if ! wget --no-check-certificate -O shadowsocks-master.zip https://github.com/shadowsocks/shadowsocks/archive/master.zip; then
        echo -e "[${red}Error${plain}] Failed to download shadowsocks python file!"
        exit 1
    fi
    # Download Shadowsocks init script
    if check_sys packageManager yum; then
        if ! wget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks -O /etc/init.d/shadowsocks; then
            echo -e "[${red}Error${plain}] Failed to download shadowsocks chkconfig file!"
            exit 1
        fi
    elif check_sys packageManager apt; then
        if ! wget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-debian -O /etc/init.d/shadowsocks; then
            echo -e "[${red}Error${plain}] Failed to download shadowsocks chkconfig file!"
            exit 1
        fi
    fi
}

# Config shadowsocks
config_shadowsocks(){
    cat > /etc/shadowsocks.json<<-EOF
{
    "server":"0.0.0.0",
    "server_port":${shadowsocksport},
    "local_address":"127.0.0.1",
    "local_port":1080,
    "password":"${shadowsockspwd}",
    "timeout":300,
    "method":"${shadowsockscipher}",
    "fast_open":false
}
EOF
}

# Firewall set
firewall_set(){
    echo -e "[${green}Info${plain}] firewall set start..."
    if centosversion 6; then
        /etc/init.d/iptables status > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            iptables -L -n | grep -i ${shadowsocksport} > /dev/null 2>&1
            if [ $? -ne 0 ]; then
                iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport ${shadowsocksport} -j ACCEPT
                iptables -I INPUT -m state --state NEW -m udp -p udp --dport ${shadowsocksport} -j ACCEPT
                /etc/init.d/iptables save
                /etc/init.d/iptables restart
            else
                echo -e "[${green}Info${plain}] port ${shadowsocksport} has already been set up."
            fi
        else
            echo -e "[${yellow}Warning${plain}] iptables looks like shutdown or not installed, please manually set it if necessary."
        fi
    elif centosversion 7; then
        systemctl status firewalld > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            default_zone=$(firewall-cmd --get-default-zone)
            firewall-cmd --permanent --zone=${default_zone} --add-port=${shadowsocksport}/tcp
            firewall-cmd --permanent --zone=${default_zone} --add-port=${shadowsocksport}/udp
            firewall-cmd --reload
        else
            echo -e "[${yellow}Warning${plain}] firewalld looks like not running or not installed, please enable port ${shadowsocksport} manually if necessary."
        fi
    fi
    echo -e "[${green}Info${plain}] firewall set completed..."
}

# Install Shadowsocks
install(){
    # Install libsodium
    if [ ! -f /usr/lib/libsodium.a ]; then
        cd ${cur_dir}
        tar zxf ${libsodium_file}.tar.gz
        cd ${libsodium_file}
        ./configure --prefix=/usr && make && make install
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] libsodium install failed!"
            install_cleanup
            exit 1
        fi
    fi

    ldconfig
    # Install Shadowsocks
    cd ${cur_dir}
    unzip -q shadowsocks-master.zip
    if [ $? -ne 0 ];then
        echo -e "[${red}Error${plain}] unzip shadowsocks-master.zip failed! please check unzip command."
        install_cleanup
        exit 1
    fi

    cd ${cur_dir}/shadowsocks-master
    python setup.py install --record /usr/local/shadowsocks_install.log

    if [ -f /usr/bin/ssserver ] || [ -f /usr/local/bin/ssserver ]; then
        chmod +x /etc/init.d/shadowsocks
        if check_sys packageManager yum; then
            chkconfig --add shadowsocks
            chkconfig shadowsocks on
        elif check_sys packageManager apt; then
            update-rc.d -f shadowsocks defaults
        fi
        /etc/init.d/shadowsocks start
    else
        echo
        echo -e "[${red}Error${plain}] Shadowsocks install failed! please visit https://teddysun.com/342.html and contact."
        install_cleanup
        exit 1
    fi

    clear
    echo
    echo -e "Congratulations, Shadowsocks-python server install completed!"
    echo -e "Your Server IP        : \033[41;37m $(get_ip) \033[0m"
    echo -e "Your Server Port      : \033[41;37m ${shadowsocksport} \033[0m"
    echo -e "Your Password         : \033[41;37m ${shadowsockspwd} \033[0m"
    echo -e "Your Encryption Method: \033[41;37m ${shadowsockscipher} \033[0m"
    echo
    echo "Welcome to visit:https://teddysun.com/342.html"
    echo "Enjoy it!"
    echo
}

# Install cleanup
install_cleanup(){
    cd ${cur_dir}
    rm -rf shadowsocks-master.zip shadowsocks-master ${libsodium_file}.tar.gz ${libsodium_file}
}

# Uninstall Shadowsocks
uninstall_shadowsocks(){
    printf "Are you sure uninstall Shadowsocks? (y/n) "
    printf "\n"
    read -p "(Default: n):" answer
    [ -z ${answer} ] && answer="n"
    if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then
        ps -ef | grep -v grep | grep -i "ssserver" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            /etc/init.d/shadowsocks stop
        fi
        if check_sys packageManager yum; then
            chkconfig --del shadowsocks
        elif check_sys packageManager apt; then
            update-rc.d -f shadowsocks remove
        fi
        # delete config file
        rm -f /etc/shadowsocks.json
        rm -f /var/run/shadowsocks.pid
        rm -f /etc/init.d/shadowsocks
        rm -f /var/log/shadowsocks.log
        if [ -f /usr/local/shadowsocks_install.log ]; then
            cat /usr/local/shadowsocks_install.log | xargs rm -rf
        fi
        echo "Shadowsocks uninstall success!"
    else
        echo
        echo "uninstall cancelled, nothing to do..."
        echo
    fi
}

# Install Shadowsocks-python
install_shadowsocks(){
    disable_selinux
    pre_install
    download_files
    config_shadowsocks
    if check_sys packageManager yum; then
        firewall_set
    fi
    install
    install_cleanup
}

# Initialization step
action=$1
[ -z $1 ] && action=install
case "$action" in
    install|uninstall)
        ${action}_shadowsocks
        ;;
    *)
        echo "Arguments error! [${action}]"
        echo "Usage: `basename $0` [install|uninstall]"
    ;;
esac


================================================
FILE: shadowsocksR
================================================
#!/bin/bash
# chkconfig: 2345 90 10
# description: A secure socks5 proxy, designed to protect your Internet traffic.

### BEGIN INIT INFO
# Provides:          ShadowsocksR
# Required-Start:    $network $syslog
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the ShadowsocksR server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

NAME=ShadowsocksR
DAEMON=/usr/local/shadowsocks/server.py
if [ -f /etc/shadowsocks-r/config.json ]; then
    CONF=/etc/shadowsocks-r/config.json
elif [ -f /etc/shadowsocks.json ]; then
    CONF=/etc/shadowsocks.json
fi
RETVAL=0

check_running(){
    PID=$(ps -ef | grep -v grep | grep -i "${DAEMON}" | awk '{print $2}')
    if [ -n "$PID" ]; then
        return 0
    else
        return 1
    fi
}

do_start(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is already running..."
        exit 0
    else
        $DAEMON -c $CONF -d start
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Starting $NAME success"
        else
            echo "Starting $NAME failed"
        fi
    fi
}

do_stop(){
    check_running
    if [ $? -eq 0 ]; then
        $DAEMON -c $CONF -d stop
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Stopping $NAME success"
        else
            echo "Stopping $NAME failed"
        fi
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_status(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is running..."
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_restart(){
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RETVAL=1
    ;;
esac

exit $RETVAL


================================================
FILE: shadowsocksR-debian
================================================
#!/bin/bash

### BEGIN INIT INFO
# Provides:          ShadowsocksR
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fast tunnel proxy that helps you bypass firewalls
# Description:       Start or stop the ShadowsocksR server
### END INIT INFO

# Author: Teddysun <i@teddysun.com>

NAME=ShadowsocksR
DAEMON=/usr/local/shadowsocks/server.py
if [ -f /etc/shadowsocks-r/config.json ]; then
    CONF=/etc/shadowsocks-r/config.json
elif [ -f /etc/shadowsocks.json ]; then
    CONF=/etc/shadowsocks.json
fi
RETVAL=0

check_running(){
    PID=$(ps -ef | grep -v grep | grep -i "${DAEMON}" | awk '{print $2}')
    if [ -n "$PID" ]; then
        return 0
    else
        return 1
    fi
}

do_start(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is already running..."
        exit 0
    else
        $DAEMON -c $CONF -d start
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Starting $NAME success"
        else
            echo "Starting $NAME failed"
        fi
    fi
}

do_stop(){
    check_running
    if [ $? -eq 0 ]; then
        $DAEMON -c $CONF -d stop
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo "Stopping $NAME success"
        else
            echo "Stopping $NAME failed"
        fi
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_status(){
    check_running
    if [ $? -eq 0 ]; then
        echo "$NAME (pid $PID) is running..."
    else
        echo "$NAME is stopped"
        RETVAL=1
    fi
}

do_restart(){
    do_stop
    sleep 0.5
    do_start
}

case "$1" in
    start|stop|restart|status)
    do_$1
    ;;
    *)
    echo "Usage: $0 { start | stop | restart | status }"
    RETVAL=1
    ;;
esac

exit $RETVAL


================================================
FILE: shadowsocksR.sh
================================================
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#=================================================================#
#   System Required:  CentOS 6,7, Debian, Ubuntu                  #
#   Description: One click Install ShadowsocksR Server            #
#   Author: Teddysun <i@teddysun.com>                             #
#   Thanks: @breakwa11 <https://twitter.com/breakwa11>            #
#   Intro:  https://shadowsocks.be/9.html                         #
#=================================================================#

clear
echo
echo "#############################################################"
echo "# One click Install ShadowsocksR Server                     #"
echo "# Intro: https://shadowsocks.be/9.html                      #"
echo "# Author: Teddysun <i@teddysun.com>                         #"
echo "# Github: https://github.com/shadowsocksr/shadowsocksr      #"
echo "#############################################################"
echo

libsodium_file="libsodium-1.0.18"
libsodium_url="https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz"
shadowsocks_r_file="shadowsocksr-3.2.2"
shadowsocks_r_url="https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz"

#Current folder
cur_dir=`pwd`
# Stream Ciphers
ciphers=(
none
aes-256-cfb
aes-192-cfb
aes-128-cfb
aes-256-cfb8
aes-192-cfb8
aes-128-cfb8
aes-256-ctr
aes-192-ctr
aes-128-ctr
chacha20-ietf
chacha20
salsa20
xchacha20
xsalsa20
rc4-md5
)
# Reference URL:
# https://github.com/shadowsocksr-rm/shadowsocks-rss/blob/master/ssr.md
# https://github.com/shadowsocksrr/shadowsocksr/commit/a3cf0254508992b7126ab1151df0c2f10bf82680
# Protocol
protocols=(
origin
verify_deflate
auth_sha1_v4
auth_sha1_v4_compatible
auth_aes128_md5
auth_aes128_sha1
auth_chain_a
auth_chain_b
auth_chain_c
auth_chain_d
auth_chain_e
auth_chain_f
)
# obfs
obfs=(
plain
http_simple
http_simple_compatible
http_post
http_post_compatible
tls1.2_ticket_auth
tls1.2_ticket_auth_compatible
tls1.2_ticket_fastauth
tls1.2_ticket_fastauth_compatible
)
# Color
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

# Make sure only root can run our script
[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1

# Disable selinux
disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}

#Check system
check_sys(){
    local checkType=$1
    local value=$2

    local release=''
    local systemPackage=''

    if [[ -f /etc/redhat-release ]]; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /etc/issue; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /etc/issue; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /etc/issue; then
        release="centos"
        systemPackage="yum"
    elif grep -Eqi "debian|raspbian" /proc/version; then
        release="debian"
        systemPackage="apt"
    elif grep -Eqi "ubuntu" /proc/version; then
        release="ubuntu"
        systemPackage="apt"
    elif grep -Eqi "centos|red hat|redhat" /proc/version; then
        release="centos"
        systemPackage="yum"
    fi

    if [[ "${checkType}" == "sysRelease" ]]; then
        if [ "${value}" == "${release}" ]; then
            return 0
        else
            return 1
        fi
    elif [[ "${checkType}" == "packageManager" ]]; then
        if [ "${value}" == "${systemPackage}" ]; then
            return 0
        else
            return 1
        fi
    fi
}

# Get version
getversion(){
    if [[ -s /etc/redhat-release ]]; then
        grep -oE  "[0-9.]+" /etc/redhat-release
    else
        grep -oE  "[0-9.]+" /etc/issue
    fi
}

# CentOS version
centosversion(){
    if check_sys sysRelease centos; then
        local code=$1
        local version="$(getversion)"
        local main_ver=${version%%.*}
        if [ "$main_ver" == "$code" ]; then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

# Get public IP address
get_ip(){
    local IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
    [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip )
    [ ! -z ${IP} ] && echo ${IP} || echo
}

get_char(){
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}

# Pre-installation settings
pre_install(){
    if check_sys packageManager yum || check_sys packageManager apt; then
        # Not support CentOS 5
        if centosversion 5; then
            echo -e "$[{red}Error${plain}] Not supported CentOS 5, please change to CentOS 6+/Debian 7+/Ubuntu 12+ and try again."
            exit 1
        fi
    else
        echo -e "[${red}Error${plain}] Your OS is not supported. please change OS to CentOS/Debian/Ubuntu and try again."
        exit 1
    fi
    # Set ShadowsocksR config password
    echo "Please enter password for ShadowsocksR:"
    read -p "(Default password: teddysun.com):" shadowsockspwd
    [ -z "${shadowsockspwd}" ] && shadowsockspwd="teddysun.com"
    echo
    echo "---------------------------"
    echo "password = ${shadowsockspwd}"
    echo "---------------------------"
    echo
    # Set ShadowsocksR config port
    while true
    do
    dport=$(shuf -i 9000-19999 -n 1)
    echo -e "Please enter a port for ShadowsocksR [1-65535]"
    read -p "(Default port: ${dport}):" shadowsocksport
    [ -z "${shadowsocksport}" ] && shadowsocksport=${dport}
    expr ${shadowsocksport} + 1 &>/dev/null
    if [ $? -eq 0 ]; then
        if [ ${shadowsocksport} -ge 1 ] && [ ${shadowsocksport} -le 65535 ] && [ ${shadowsocksport:0:1} != 0 ]; then
            echo
            echo "---------------------------"
            echo "port = ${shadowsocksport}"
            echo "---------------------------"
            echo
            break
        fi
    fi
    echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]"
    done

    # Set shadowsocksR config stream ciphers
    while true
    do
    echo -e "Please select stream cipher for ShadowsocksR:"
    for ((i=1;i<=${#ciphers[@]};i++ )); do
        hint="${ciphers[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -p "Which cipher you'd select(Default: ${ciphers[1]}):" pick
    [ -z "$pick" ] && pick=2
    expr ${pick} + 1 &>/dev/null
    if [ $? -ne 0 ]; then
        echo -e "[${red}Error${plain}] Please enter a number"
        continue
    fi
    if [[ "$pick" -lt 1 || "$pick" -gt ${#ciphers[@]} ]]; then
        echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#ciphers[@]}"
        continue
    fi
    shadowsockscipher=${ciphers[$pick-1]}
    echo
    echo "---------------------------"
    echo "cipher = ${shadowsockscipher}"
    echo "---------------------------"
    echo
    break
    done

    # Set shadowsocksR config protocol
    while true
    do
    echo -e "Please select protocol for ShadowsocksR:"
    for ((i=1;i<=${#protocols[@]};i++ )); do
        hint="${protocols[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -p "Which protocol you'd select(Default: ${protocols[0]}):" protocol
    [ -z "$protocol" ] && protocol=1
    expr ${protocol} + 1 &>/dev/null
    if [ $? -ne 0 ]; then
        echo -e "[${red}Error${plain}] Input error, please input a number"
        continue
    fi
    if [[ "$protocol" -lt 1 || "$protocol" -gt ${#protocols[@]} ]]; then
        echo -e "[${red}Error${plain}] Input error, please input a number between 1 and ${#protocols[@]}"
        continue
    fi
    shadowsockprotocol=${protocols[$protocol-1]}
    echo
    echo "---------------------------"
    echo "protocol = ${shadowsockprotocol}"
    echo "---------------------------"
    echo
    break
    done

    # Set shadowsocksR config obfs
    while true
    do
    echo -e "Please select obfs for ShadowsocksR:"
    for ((i=1;i<=${#obfs[@]};i++ )); do
        hint="${obfs[$i-1]}"
        echo -e "${green}${i}${plain}) ${hint}"
    done
    read -p "Which obfs you'd select(Default: ${obfs[0]}):" r_obfs
    [ -z "$r_obfs" ] && r_obfs=1
    expr ${r_obfs} + 1 &>/dev/null
    if [ $? -ne 0 ]; then
        echo -e "[${red}Error${plain}] Input error, please input a number"
        continue
    fi
    if [[ "$r_obfs" -lt 1 || "$r_obfs" -gt ${#obfs[@]} ]]; then
        echo -e "[${red}Error${plain}] Input error, please input a number between 1 and ${#obfs[@]}"
        continue
    fi
    shadowsockobfs=${obfs[$r_obfs-1]}
    echo
    echo "---------------------------"
    echo "obfs = ${shadowsockobfs}"
    echo "---------------------------"
    echo
    break
    done

    echo
    echo "Press any key to start...or Press Ctrl+C to cancel"
    char=`get_char`
    # Install necessary dependencies
    if check_sys packageManager yum; then
        yum install -y python python-devel python-setuptools openssl openssl-devel curl wget unzip gcc automake autoconf make libtool
    elif check_sys packageManager apt; then
        apt-get -y update
        apt-get -y install python python-dev python-setuptools openssl libssl-dev curl wget unzip gcc automake autoconf make libtool
    fi
    cd ${cur_dir}
}

# Download files
download_files(){
    # Download libsodium file
    if ! wget --no-check-certificate -O ${libsodium_file}.tar.gz ${libsodium_url}; then
        echo -e "[${red}Error${plain}] Failed to download ${libsodium_file}.tar.gz!"
        exit 1
    fi
    # Download ShadowsocksR file
    if ! wget --no-check-certificate -O ${shadowsocks_r_file}.tar.gz ${shadowsocks_r_url}; then
        echo -e "[${red}Error${plain}] Failed to download ShadowsocksR file!"
        exit 1
    fi
    # Download ShadowsocksR init script
    if check_sys packageManager yum; then
        if ! wget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocksR -O /etc/init.d/shadowsocks; then
            echo -e "[${red}Error${plain}] Failed to download ShadowsocksR chkconfig file!"
            exit 1
        fi
    elif check_sys packageManager apt; then
        if ! wget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocksR-debian -O /etc/init.d/shadowsocks; then
            echo -e "[${red}Error${plain}] Failed to download ShadowsocksR chkconfig file!"
            exit 1
        fi
    fi
}

# Firewall set
firewall_set(){
    echo -e "[${green}Info${plain}] firewall set start..."
    if centosversion 6; then
        /etc/init.d/iptables status > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            iptables -L -n | grep -i ${shadowsocksport} > /dev/null 2>&1
            if [ $? -ne 0 ]; then
                iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport ${shadowsocksport} -j ACCEPT
                iptables -I INPUT -m state --state NEW -m udp -p udp --dport ${shadowsocksport} -j ACCEPT
                /etc/init.d/iptables save
                /etc/init.d/iptables restart
            else
                echo -e "[${green}Info${plain}] port ${shadowsocksport} has been set up."
            fi
        else
            echo -e "[${yellow}Warning${plain}] iptables looks like shutdown or not installed, please manually set it if necessary."
        fi
    elif centosversion 7; then
        systemctl status firewalld > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            default_zone=$(firewall-cmd --get-default-zone)
            firewall-cmd --permanent --zone=${default_zone} --add-port=${shadowsocksport}/tcp
            firewall-cmd --permanent --zone=${default_zone} --add-port=${shadowsocksport}/udp
            firewall-cmd --reload
        else
            echo -e "[${yellow}Warning${plain}] firewalld looks like not running or not installed, please enable port ${shadowsocksport} manually if necessary."
        fi
    fi
    echo -e "[${green}Info${plain}] firewall set completed..."
}

# Config ShadowsocksR
config_shadowsocks(){
    cat > /etc/shadowsocks.json<<-EOF
{
    "server":"0.0.0.0",
    "server_ipv6":"[::]",
    "server_port":${shadowsocksport},
    "local_address":"127.0.0.1",
    "local_port":1080,
    "password":"${shadowsockspwd}",
    "timeout":120,
    "method":"${shadowsockscipher}",
    "protocol":"${shadowsockprotocol}",
    "protocol_param":"",
    "obfs":"${shadowsockobfs}",
    "obfs_param":"",
    "redirect":"",
    "dns_ipv6":false,
    "fast_open":false,
    "workers":1
}
EOF
}

# Install ShadowsocksR
install(){
    # Install libsodium
    if [ ! -f /usr/lib/libsodium.a ]; then
        cd ${cur_dir}
        tar zxf ${libsodium_file}.tar.gz
        cd ${libsodium_file}
        ./configure --prefix=/usr && make && make install
        if [ $? -ne 0 ]; then
            echo -e "[${red}Error${plain}] libsodium install failed!"
            install_cleanup
            exit 1
        fi
    fi

    ldconfig
    # Install ShadowsocksR
    cd ${cur_dir}
    tar zxf ${shadowsocks_r_file}.tar.gz
    mv ${shadowsocks_r_file}/shadowsocks /usr/local/
    if [ -f /usr/local/shadowsocks/server.py ]; then
        chmod +x /etc/init.d/shadowsocks
        if check_sys packageManager yum; then
            chkconfig --add shadowsocks
            chkconfig shadowsocks on
        elif check_sys packageManager apt; then
            update-rc.d -f shadowsocks defaults
        fi
        /etc/init.d/shadowsocks start

        clear
        echo
        echo -e "Congratulations, ShadowsocksR server install completed!"
        echo -e "Your Server IP        : \033[41;37m $(get_ip) \033[0m"
        echo -e "Your Server Port      : \033[41;37m ${shadowsocksport} \033[0m"
        echo -e "Your Password         : \033[41;37m ${shadowsockspwd} \033[0m"
        echo -e "Your Protocol         : \033[41;37m ${shadowsockprotocol} \033[0m"
        echo -e "Your obfs             : \033[41;37m ${shadowsockobfs} \033[0m"
        echo -e "Your Encryption Method: \033[41;37m ${shadowsockscipher} \033[0m"
        echo
        echo "Welcome to visit:https://shadowsocks.be/9.html"
        echo "Enjoy it!"
        echo
    else
        echo "ShadowsocksR install failed, please Email to Teddysun <i@teddysun.com> and contact"
        install_cleanup
        exit 1
    fi
}

# Install cleanup
install_cleanup(){
    cd ${cur_dir}
    rm -rf ${shadowsocks_r_file}.tar.gz ${shadowsocks_r_file} ${libsodium_file}.tar.gz ${libsodium_file}
}


# Uninstall ShadowsocksR
uninstall_shadowsocksr(){
    printf "Are you sure uninstall ShadowsocksR? (y/n)"
    printf "\n"
    read -p "(Default: n):" answer
    [ -z ${answer} ] && answer="n"
    if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then
        /etc/init.d/shadowsocks status > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            /etc/init.d/shadowsocks stop
        fi
        if check_sys packageManager yum; then
            chkconfig --del shadowsocks
        elif check_sys packageManager apt; then
            update-rc.d -f shadowsocks remove
        fi
        rm -f /etc/shadowsocks.json
        rm -f /etc/init.d/shadowsocks
        rm -f /var/log/shadowsocks.log
        rm -rf /usr/local/shadowsocks
        echo "ShadowsocksR uninstall success!"
    else
        echo
        echo "uninstall cancelled, nothing to do..."
        echo
    fi
}

# Install ShadowsocksR
install_shadowsocksr(){
    disable_selinux
    pre_install
    download_files
    config_shadowsocks
    if check_sys packageManager yum; then
        firewall_set
    fi
    install
    install_cleanup
}

# Initialization step
action=$1
[ -z $1 ] && action=install
case "$action" in
    install|uninstall)
        ${action}_shadowsocksr
        ;;
    *)
        echo "Arguments error! [${action}]"
        echo "Usage: `basename $0` [install|uninstall]"
        ;;
esac
Download .txt
gitextract_yj3jp4x6/

├── Readme.md
├── docker/
│   ├── go-shadowsocks2/
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   ├── build_go-shadowsocks2.sh
│   │   ├── go-shadowsocks2.sh
│   │   ├── v2ray-plugin.sh
│   │   └── xray-plugin.sh
│   ├── shadowsocks-go/
│   │   ├── .dockerignore
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   ├── config_sample.json
│   │   └── shadowsocks-go.sh
│   ├── shadowsocks-libev/
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── Dockerfile_edge.architecture
│   │   ├── README.md
│   │   ├── build_v2ray-plugin.sh
│   │   ├── build_xray-plugin.sh
│   │   ├── config_sample.json
│   │   ├── v2ray-plugin.sh
│   │   └── xray-plugin.sh
│   ├── shadowsocks-python/
│   │   ├── .dockerignore
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   └── config_sample.json
│   ├── shadowsocks-r/
│   │   ├── .dockerignore
│   │   ├── Dockerfile
│   │   ├── Dockerfile.architecture
│   │   ├── README.md
│   │   └── config_sample.json
│   └── shadowsocks-rust/
│       ├── Dockerfile
│       ├── Dockerfile.alpine
│       ├── Dockerfile.architecture
│       ├── Dockerfile.debian
│       ├── Dockerfile_edge.alpine
│       ├── README.md
│       ├── build_v2ray-plugin.sh
│       ├── build_xray-plugin.sh
│       ├── config_sample.json
│       ├── shadowsocks-rust-alpine.sh
│       ├── shadowsocks-rust-debian.sh
│       ├── v2ray-plugin.sh
│       └── xray-plugin.sh
├── haproxy.sh
├── sample_config/
│   ├── shadowsocks-go/
│   │   └── config.json
│   ├── shadowsocks-libev/
│   │   └── config.json
│   ├── shadowsocks-manager/
│   │   └── config.json
│   ├── shadowsocks-python/
│   │   └── config.json
│   └── shadowsocks-r/
│       └── config.json
├── shadowsocks
├── shadowsocks-all.sh
├── shadowsocks-crond.sh
├── shadowsocks-debian
├── shadowsocks-go
├── shadowsocks-go-debian
├── shadowsocks-go.sh
├── shadowsocks-libev
├── shadowsocks-libev-debian
├── shadowsocks-libev-debian.sh
├── shadowsocks-libev.sh
├── shadowsocks-manager
├── shadowsocks.sh
├── shadowsocksR
├── shadowsocksR-debian
└── shadowsocksR.sh
Condensed preview — 67 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (201K chars).
[
  {
    "path": "Readme.md",
    "chars": 1211,
    "preview": "![Shadowsocks](https://github.com/teddysun/shadowsocks_install/raw/master/shadowsocks.png)\n# Auto install Shadowsocks Se"
  },
  {
    "path": "docker/go-shadowsocks2/Dockerfile.architecture",
    "chars": 1048,
    "preview": "# Dockerfile for go-shadowsocks2 based alpine\n# Copyright (C) 2019 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# h"
  },
  {
    "path": "docker/go-shadowsocks2/README.md",
    "chars": 3229,
    "preview": "## Go-shadowsocks2 Docker Image by Teddysun\n\n[go-shadowsocks2][1] is a fresh implementation of Shadowsocks in Go which c"
  },
  {
    "path": "docker/go-shadowsocks2/build_go-shadowsocks2.sh",
    "chars": 1320,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for build multi-architectures go-shadowsocks2 binary file\n# \n# Supported architectu"
  },
  {
    "path": "docker/go-shadowsocks2/go-shadowsocks2.sh",
    "chars": 1359,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for go-shadowsocks2 based alpine with Docker image\n# \n# Copyright (C) 2019 - 2020 T"
  },
  {
    "path": "docker/go-shadowsocks2/v2ray-plugin.sh",
    "chars": 1404,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for go-shadowsocks2 supported SIP003 plugins based alpine with Docker image\n# \n# Co"
  },
  {
    "path": "docker/go-shadowsocks2/xray-plugin.sh",
    "chars": 1345,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for go-shadowsocks2 supported SIP003 plugins based alpine with Docker image\n# \n# Co"
  },
  {
    "path": "docker/shadowsocks-go/.dockerignore",
    "chars": 23,
    "preview": ".dockerignore\nREADME.md"
  },
  {
    "path": "docker/shadowsocks-go/Dockerfile",
    "chars": 617,
    "preview": "# Dockerfile for Shadowsocks-go based alpine\n# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# ht"
  },
  {
    "path": "docker/shadowsocks-go/Dockerfile.architecture",
    "chars": 656,
    "preview": "# Dockerfile for Shadowsocks-go based alpine\n# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# ht"
  },
  {
    "path": "docker/shadowsocks-go/README.md",
    "chars": 1606,
    "preview": "## Shadowsocks-go Docker Image by Teddysun\n\n[Shadowsocks-go][1] is a lightweight tunnel proxy which can help you get thr"
  },
  {
    "path": "docker/shadowsocks-go/config_sample.json",
    "chars": 148,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"server_port\":9000,\n    \"local_port\":1080,\n    \"password\":\"password0\",\n    \"method\":\"aes-2"
  },
  {
    "path": "docker/shadowsocks-go/shadowsocks-go.sh",
    "chars": 1354,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for shadowsocks-go based alpine with Docker image\n# \n# Copyright (C) 2019 - 2020 Te"
  },
  {
    "path": "docker/shadowsocks-libev/Dockerfile",
    "chars": 1735,
    "preview": "# Dockerfile for shadowsocks-libev based alpine\n# Copyright (C) 2018 - 2026 Teddysun <i@teddysun.com>\n# Reference URL:\n#"
  },
  {
    "path": "docker/shadowsocks-libev/Dockerfile.architecture",
    "chars": 1794,
    "preview": "# Dockerfile for shadowsocks-libev based alpine\n# Copyright (C) 2018 - 2026 Teddysun <i@teddysun.com>\n# Reference URL:\n#"
  },
  {
    "path": "docker/shadowsocks-libev/Dockerfile_edge.architecture",
    "chars": 1052,
    "preview": "# Dockerfile for shadowsocks-libev based alpine\n# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n#"
  },
  {
    "path": "docker/shadowsocks-libev/README.md",
    "chars": 2899,
    "preview": "## Shadowsocks-libev Docker Image by Teddysun\n\n[shadowsocks-libev][1] is a lightweight secured socks5 proxy for embedded"
  },
  {
    "path": "docker/shadowsocks-libev/build_v2ray-plugin.sh",
    "chars": 1349,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for build multi-architectures v2ray-plugin binary file\n# \n# Supported architectures"
  },
  {
    "path": "docker/shadowsocks-libev/build_xray-plugin.sh",
    "chars": 1301,
    "preview": "#!/bin/bash\n#\n# This is a Shell script for build multi-architectures xray-plugin binary file\n# \n# Supported architecture"
  },
  {
    "path": "docker/shadowsocks-libev/config_sample.json",
    "chars": 201,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"server_port\":9000,\n    \"password\":\"password0\",\n    \"timeout\":300,\n    \"method\":\"aes-256-g"
  },
  {
    "path": "docker/shadowsocks-libev/v2ray-plugin.sh",
    "chars": 1477,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for shadowsocks-libev based alpine with Docker image\n# \n# Copyright (C) 2019 - 2021"
  },
  {
    "path": "docker/shadowsocks-libev/xray-plugin.sh",
    "chars": 1347,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for shadowsocks-libev supported SIP003 plugins based alpine with Docker image\n# \n# "
  },
  {
    "path": "docker/shadowsocks-python/.dockerignore",
    "chars": 23,
    "preview": ".dockerignore\nREADME.md"
  },
  {
    "path": "docker/shadowsocks-python/Dockerfile",
    "chars": 732,
    "preview": "# Dockerfile for Shadowsocks-Python based alpine\n# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n"
  },
  {
    "path": "docker/shadowsocks-python/Dockerfile.architecture",
    "chars": 732,
    "preview": "# Dockerfile for Shadowsocks-Python based alpine\n# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n"
  },
  {
    "path": "docker/shadowsocks-python/README.md",
    "chars": 1712,
    "preview": "## Shadowsocks-Python Docker Image by Teddysun\n\n[Shadowsocks][1] is a lightweight secured socks5 proxy for embedded devi"
  },
  {
    "path": "docker/shadowsocks-python/config_sample.json",
    "chars": 203,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"server_port\":9000,\n    \"local_address\":\"127.0.0.1\",\n    \"local_port\":1080,\n    \"password\""
  },
  {
    "path": "docker/shadowsocks-r/.dockerignore",
    "chars": 23,
    "preview": ".dockerignore\nREADME.md"
  },
  {
    "path": "docker/shadowsocks-r/Dockerfile",
    "chars": 765,
    "preview": "# Dockerfile for ShadowsocksR based alpine\n# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# http"
  },
  {
    "path": "docker/shadowsocks-r/Dockerfile.architecture",
    "chars": 765,
    "preview": "# Dockerfile for ShadowsocksR based alpine\n# Copyright (C) 2018 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# http"
  },
  {
    "path": "docker/shadowsocks-r/README.md",
    "chars": 1866,
    "preview": "## ShadowsocksR Docker Image by Teddysun\n\n[shadowsocksr][1] is a lightweight secured socks5 proxy for embedded devices a"
  },
  {
    "path": "docker/shadowsocks-r/config_sample.json",
    "chars": 376,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"server_ipv6\":\"::\",\n    \"server_port\":9000,\n    \"local_address\":\"127.0.0.1\",\n    \"local_po"
  },
  {
    "path": "docker/shadowsocks-rust/Dockerfile",
    "chars": 1942,
    "preview": "# Dockerfile for shadowsocks-rust based alpine\n# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# "
  },
  {
    "path": "docker/shadowsocks-rust/Dockerfile.alpine",
    "chars": 1351,
    "preview": "# Dockerfile for shadowsocks-rust based alpine\n# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# "
  },
  {
    "path": "docker/shadowsocks-rust/Dockerfile.architecture",
    "chars": 2046,
    "preview": "# Dockerfile for shadowsocks-rust based alpine\n# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# "
  },
  {
    "path": "docker/shadowsocks-rust/Dockerfile.debian",
    "chars": 1322,
    "preview": "# Dockerfile for shadowsocks-rust based debian\n# Copyright (C) 2020 - 2025 Teddysun <i@teddysun.com>\n# Reference URL:\n# "
  },
  {
    "path": "docker/shadowsocks-rust/Dockerfile_edge.alpine",
    "chars": 988,
    "preview": "# Dockerfile for shadowsocks-rust based alpine\n# Copyright (C) 2020 - 2024 Teddysun <i@teddysun.com>\n# Reference URL:\n# "
  },
  {
    "path": "docker/shadowsocks-rust/README.md",
    "chars": 2881,
    "preview": "## Shadowsocks-rust Docker Image by Teddysun\n\n![Shadowsocks](https://github.com/teddysun/shadowsocks_install/raw/master/"
  },
  {
    "path": "docker/shadowsocks-rust/build_v2ray-plugin.sh",
    "chars": 1349,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for build multi-architectures v2ray-plugin binary file\n# \n# Supported architectures"
  },
  {
    "path": "docker/shadowsocks-rust/build_xray-plugin.sh",
    "chars": 1301,
    "preview": "#!/bin/bash\n#\n# This is a Shell script for build multi-architectures xray-plugin binary file\n# \n# Supported architecture"
  },
  {
    "path": "docker/shadowsocks-rust/config_sample.json",
    "chars": 201,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"server_port\":9000,\n    \"password\":\"password0\",\n    \"timeout\":300,\n    \"method\":\"aes-256-g"
  },
  {
    "path": "docker/shadowsocks-rust/shadowsocks-rust-alpine.sh",
    "chars": 2147,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for shadowsocks-rust based alpine with Docker image\n# \n# Copyright (C) 2019 - 2024 "
  },
  {
    "path": "docker/shadowsocks-rust/shadowsocks-rust-debian.sh",
    "chars": 2117,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for shadowsocks-rust based debian with Docker image\n# \n# Copyright (C) 2019 - 2024 "
  },
  {
    "path": "docker/shadowsocks-rust/v2ray-plugin.sh",
    "chars": 1406,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for shadowsocks-libev supported SIP003 plugins based alpine with Docker image\n# \n# "
  },
  {
    "path": "docker/shadowsocks-rust/xray-plugin.sh",
    "chars": 1346,
    "preview": "#!/bin/sh\n#\n# This is a Shell script for shadowsocks-rust supported SIP003 plugins based alpine with Docker image\n# \n# C"
  },
  {
    "path": "haproxy.sh",
    "chars": 7217,
    "preview": "#!/usr/bin/env bash\n#\n# System Required:  CentOS, Debian, Ubuntu\n#\n# Description: Install haproxy for Shadowsocks server"
  },
  {
    "path": "sample_config/shadowsocks-go/config.json",
    "chars": 222,
    "preview": "{\n    \"port_password\":{\n         \"9000\":\"password0\",\n         \"9001\":\"password1\",\n         \"9002\":\"password2\",\n         "
  },
  {
    "path": "sample_config/shadowsocks-libev/config.json",
    "chars": 223,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"server_port\":9000,\n    \"password\":\"password0\",\n    \"timeout\":300,\n    \"user\":\"nobody\",\n  "
  },
  {
    "path": "sample_config/shadowsocks-manager/config.json",
    "chars": 321,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"port_password\":{\n         \"9000\":\"password0\",\n         \"9001\":\"password1\",\n         \"9002"
  },
  {
    "path": "sample_config/shadowsocks-python/config.json",
    "chars": 326,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"local_address\":\"127.0.0.1\",\n    \"local_port\":1080,\n    \"port_password\":{\n         \"9000\":"
  },
  {
    "path": "sample_config/shadowsocks-r/config.json",
    "chars": 527,
    "preview": "{\n    \"server\":\"0.0.0.0\",\n    \"server_ipv6\": \"[::]\",\n    \"local_address\":\"127.0.0.1\",\n    \"local_port\":1080,\n    \"port_p"
  },
  {
    "path": "shadowsocks",
    "chars": 2037,
    "preview": "#!/bin/bash\n# chkconfig: 2345 90 10\n# description: A secure socks5 proxy, designed to protect your Internet traffic.\n\n##"
  },
  {
    "path": "shadowsocks-all.sh",
    "chars": 23058,
    "preview": "#!/usr/bin/env bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n#\n# Auto install"
  },
  {
    "path": "shadowsocks-crond.sh",
    "chars": 1687,
    "preview": "#!/usr/bin/env bash\n#=================================================================#\n#   System Required:  CentOS, De"
  },
  {
    "path": "shadowsocks-debian",
    "chars": 1966,
    "preview": "#!/bin/bash\n\n### BEGIN INIT INFO\n# Provides:          Shadowsocks\n# Required-Start:    $network $local_fs $remote_fs\n# R"
  },
  {
    "path": "shadowsocks-go",
    "chars": 2381,
    "preview": "#!/bin/bash\n# chkconfig: 2345 90 10\n# description: A secure socks5 proxy, designed to protect your Internet traffic.\n\n##"
  },
  {
    "path": "shadowsocks-go-debian",
    "chars": 2187,
    "preview": "#!/bin/bash\n\n### BEGIN INIT INFO\n# Provides:          Shadowsocks-go\n# Required-Start:    $network $local_fs $remote_fs\n"
  },
  {
    "path": "shadowsocks-go.sh",
    "chars": 13055,
    "preview": "#!/usr/bin/env bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n#==============="
  },
  {
    "path": "shadowsocks-libev",
    "chars": 2196,
    "preview": "#!/usr/bin/env bash\n# chkconfig: 2345 90 10\n# description: A secure socks5 proxy, designed to protect your Internet traf"
  },
  {
    "path": "shadowsocks-libev-debian",
    "chars": 2125,
    "preview": "#!/usr/bin/env bash\n\n### BEGIN INIT INFO\n# Provides:          Shadowsocks-libev\n# Required-Start:    $network $local_fs "
  },
  {
    "path": "shadowsocks-libev-debian.sh",
    "chars": 15907,
    "preview": "#!/usr/bin/env bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n#==============="
  },
  {
    "path": "shadowsocks-libev.sh",
    "chars": 18082,
    "preview": "#!/usr/bin/env bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n#==============="
  },
  {
    "path": "shadowsocks-manager",
    "chars": 2762,
    "preview": "#!/usr/bin/env bash\n# chkconfig: 2345 90 10\n# description: A secure socks5 proxy, designed to protect your Internet traf"
  },
  {
    "path": "shadowsocks.sh",
    "chars": 13842,
    "preview": "#!/usr/bin/env bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n#==============="
  },
  {
    "path": "shadowsocksR",
    "chars": 1927,
    "preview": "#!/bin/bash\n# chkconfig: 2345 90 10\n# description: A secure socks5 proxy, designed to protect your Internet traffic.\n\n##"
  },
  {
    "path": "shadowsocksR-debian",
    "chars": 1856,
    "preview": "#!/bin/bash\n\n### BEGIN INIT INFO\n# Provides:          ShadowsocksR\n# Required-Start:    $network $local_fs $remote_fs\n# "
  },
  {
    "path": "shadowsocksR.sh",
    "chars": 16220,
    "preview": "#!/usr/bin/env bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n#==============="
  }
]

About this extraction

This page contains the full source code of the teddysun/shadowsocks_install GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 67 files (181.8 KB), approximately 57.6k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!