From 400419b55b1e5bb1b5c05cbb7b433eeb6efe80c2 Mon Sep 17 00:00:00 2001 From: Neur0toxine Date: Fri, 18 Jun 2021 18:17:13 +0300 Subject: [PATCH] Initial commit --- .env.dist | 32 ++++++++ .gitignore | 3 + Dockerfile | 18 +++++ README.md | 13 +++ config/nginx.conf | 68 ++++++++++++++++ config/nginx_ss.conf.sh | 54 +++++++++++++ config/shadowsocks-libev_config.json.sh | 17 ++++ docker-compose.yml | 23 ++++++ entrypoint.sh | 102 ++++++++++++++++++++++++ 9 files changed, 330 insertions(+) create mode 100644 .env.dist create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 config/nginx.conf create mode 100644 config/nginx_ss.conf.sh create mode 100644 config/shadowsocks-libev_config.json.sh create mode 100644 docker-compose.yml create mode 100644 entrypoint.sh diff --git a/.env.dist b/.env.dist new file mode 100644 index 0000000..7076ba6 --- /dev/null +++ b/.env.dist @@ -0,0 +1,32 @@ +# Proxy password. +PASSWORD=B1922A0B-1D77-40C6-8119-497AB81BC7A4 + +# Encryption algorithm. Default is good enough for both powerful and low-end devices. +ENCRYPT=xchacha20-ietf-poly1305 + +# DNS servers which will be used by the proxy. +DNS_SERVERS=1.1.1.1,1.0.0.1 + +# Path to V2Ray. This path will be used during client configuration. I suggest using some random value, like CRC32. +V2_PATH=/v2ray + +# Path to QR code and connection string. This will be accessible without any authentication, so, use long random string. +QR_PATH=/qr_code + +# Set to "no" if you don't want to make connection data accessible via path provided in the previous value. +GENERATE_QR=yes + +# Specify server domain here. +DOMAIN=example.com + +# Specify server port here (443 is HIGHLY RECOMMENDED because HTTPS uses it). +PORT=443 + +# Path to domain's TLS ceritificate inside container. +TLS_CERT=/etc/ssl/ssl.pem + +# Path to domain's TLS private key inside container. +TLS_KEY=/etc/ssl/ssl.key + +# Path to dhparams.pem inside container. Can be generated automatically if it's not passed via volume or any other means. +TLS_DHPARAM=/etc/ssl/dhparams.pem diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cc3d49 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.key +*.pem +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3b2ae77 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM alpine:latest + +ARG V2RAY_VERSION=v1.3.1 + +RUN set -ex \ + && apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing wget libqrencode shadowsocks-libev nginx jq bash sudo \ + && mkdir -p /etc/shadowsocks-libev /v2raybin /wwwroot \ + && wget -O- "https://github.com/shadowsocks/v2ray-plugin/releases/download/${V2RAY_VERSION}/v2ray-plugin-linux-amd64-${V2RAY_VERSION}.tar.gz" | \ + tar zx -C /v2raybin \ + && install /v2raybin/v2ray-plugin_linux_amd64 /usr/bin/v2ray-plugin \ + && rm -rf /v2raybin + +COPY config/ /config +COPY entrypoint.sh /entrypoint.sh + +RUN chmod +x /entrypoint.sh + +CMD /entrypoint.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..78d8abb --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Shadowsocks + V2Ray in Docker + +Preconfigured solution for running Shadowsocks proxy with V2Ray inside Docker container. +You'll need a working domain for this solution. + +Usage: + +1. Copy `.env.dist` to `.env` +2. Replace demo values with your own (especially password). +3. Add your domain certificate to the `cert.pem` file. +4. Add your domain private key to the `cert.key` file. +5. Generate dhparams.pem using command `openssl dhparam -out "${TLS_DHPARAM}" 4096` or just remove like `- ./dhparams.pem:${TLS_DHPARAM}` from the `docker-compose.yml`. +6. Run `docker-compose up -d`. diff --git a/config/nginx.conf b/config/nginx.conf new file mode 100644 index 0000000..eca7724 --- /dev/null +++ b/config/nginx.conf @@ -0,0 +1,68 @@ +user www-data; +worker_processes auto; +worker_cpu_affinity auto; +pcre_jit on; +pid /run/nginx.pid; +worker_rlimit_nofile 131072; +include /etc/nginx/modules-enabled/*.conf; + +events { +worker_connections 4000; +multi_accept on; +use epoll; +epoll_events 512; +} + +http { + +## +# Basic Settings +## + +sendfile on; +tcp_nopush on; +tcp_nodelay on; +keepalive_timeout 60; +client_body_timeout 12; +client_header_timeout 12; +send_timeout 30; +keepalive_requests 2000; +reset_timedout_connection on; +types_hash_max_size 2048; +server_tokens off; +server_names_hash_max_size 4096; + +client_body_buffer_size 128K; +client_header_buffer_size 3m; +client_body_in_single_buffer on; +client_max_body_size 8m; +large_client_header_buffers 4 256k; + +open_file_cache max=200000 inactive=20s; +open_file_cache_valid 30s; +open_file_cache_min_uses 2; +open_file_cache_errors on; + +include /etc/nginx/mime.types; +default_type application/octet-stream; + +## +# Logging Settings +## + +access_log off; +error_log /var/log/nginx/error.log crit; + +## +# Gzip Settings +## + +gzip off; + +## +# Virtual Host Configs +## + +include /etc/nginx/conf.d/*.conf; +include /etc/nginx/sites-available/*; +} \ No newline at end of file diff --git a/config/nginx_ss.conf.sh b/config/nginx_ss.conf.sh new file mode 100644 index 0000000..48d7476 --- /dev/null +++ b/config/nginx_ss.conf.sh @@ -0,0 +1,54 @@ +#!/bin/bash +cat </dev/null; then + adduser -s /bin/false -S -D -H www-data +fi + +if ! id shadowsocks &>/dev/null; then + adduser -s /bin/false -S -D -H shadowsocks +fi + +bash /config/shadowsocks-libev_config.json.sh > /etc/shadowsocks-libev/config.json +echo /etc/shadowsocks-libev/config.json has been updated with following contents: +cat /etc/shadowsocks-libev/config.json +echo + +mkdir -p /etc/nginx/conf.d +mv /config/nginx.conf /etc/nginx/nginx.conf +bash /config/nginx_ss.conf.sh > /etc/nginx/conf.d/ss.conf +echo /etc/nginx/conf.d/ss.conf has been updated with following contents: +cat /etc/nginx/conf.d/ss.conf +echo + +if [[ "$GENERATE_QR" = "yes" ]]; then + [ ! -d /wwwroot/${QR_PATH} ] && mkdir /wwwroot/${QR_PATH} + plugin=$(echo -n "v2ray;path=${V2_PATH};host=${DOMAIN};tls;fast-open" | sed -e 's/\//%2F/g' -e 's/=/%3D/g' -e 's/;/%3B/g') + ss="ss://$(echo -n ${ENCRYPT}:${PASSWORD} | base64 -w 0)@${DOMAIN}:${PORT}?plugin=${plugin}" + echo "Shadowsocks Account" > /wwwroot/${QR_PATH}/index.html + echo "

${ss}

" | tr -d '\n' >> /wwwroot/${QR_PATH}/index.html + echo "" >> /wwwroot/${QR_PATH}/index.html + echo "" >> /wwwroot/${QR_PATH}/index.html + echo -n "${ss}" | qrencode -s 6 -o /wwwroot/${QR_PATH}/vpn.png +fi + +chown www-data:www-data -R /wwwroot +echo Running nginx and shadowsocks proxy... + +sudo -u shadowsocks ss-server -c /etc/shadowsocks-libev/config.json & +rm -rf /etc/nginx/sites-enabled/default +nginx -g 'daemon off;'