Init import

This commit is contained in:
Samuel Huang
2021-08-16 00:48:32 +10:00
commit 5ad15c3c93
17 changed files with 985 additions and 0 deletions

6
.dockerignore Normal file
View File

@@ -0,0 +1,6 @@
# Ignore all
**
# Allow only docker duild files
!Dockerfile.*
!*.sh

84
.github/workflows/docker-buildx-dev.yml vendored Normal file
View File

@@ -0,0 +1,84 @@
name: docker-buildx-dev
on:
push:
branches: dev
jobs:
multi-arch-dev:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
version: latest
-
name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push multi-arch dev
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.amd64
platforms: |
linux/amd64
linux/arm64
linux/arm/v7
linux/arm/v6
push: true
tags: ${{ github.repository }}:dev
-
name: Build and push AMD64
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.amd64
platforms: linux/amd64
push: true
tags: ${{ github.repository }}:amd64dev
-
name: Build and push ARM64v8
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.arm64
platforms: linux/arm64
push: true
tags: ${{ github.repository }}:arm64dev
-
name: Build and push ARM32v7
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.arm
platforms: linux/arm/v7
push: true
tags: ${{ github.repository }}:armv7dev
-
name: Build and push ARM32v6
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.arm
platforms: linux/arm/v6
push: true
tags: ${{ github.repository }}:armdev

View File

@@ -0,0 +1,84 @@
name: docker-buildx-latest
on:
push:
branches: master
jobs:
multi-arch-latest:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
version: latest
-
name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push multi-arch latest
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.amd64
platforms: |
linux/amd64
linux/arm64
linux/arm/v7
linux/arm/v6
push: true
tags: ${{ github.repository }}:latest
-
name: Build and push AMD64
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.amd64
platforms: linux/amd64
push: true
tags: ${{ github.repository }}:amd64
-
name: Build and push ARM64v8
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.arm64
platforms: linux/arm64
push: true
tags: ${{ github.repository }}:arm64
-
name: Build and push ARM32v7
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.arm
platforms: linux/arm/v7
push: true
tags: ${{ github.repository }}:armv7
-
name: Build and push ARM32v6
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.arm
platforms: linux/arm/v6
push: true
tags: ${{ github.repository }}:arm

41
Dockerfile.amd64 Normal file
View File

@@ -0,0 +1,41 @@
FROM golang:1.16-alpine as builder
ARG XRAYVER='v1.4.2'
RUN apk add --no-cache bash git build-base
WORKDIR /go/src/XTLS/Xray-core
RUN git clone https://github.com/XTLS/Xray-core.git . && \
git checkout ${XRAYVER} && \
go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
FROM alpine:3.14
COPY --from=builder /go/src/XTLS/Xray-core/xray /usr/local/bin/
RUN apk update && apk add bash openssl curl jq moreutils \
bind-tools whois dnscrypt-proxy ca-certificates proxychains-ng npm
RUN npm config set unsafe-perm true
RUN npm install -g qrcode-terminal
ENV DNSPORT="53"
RUN sed -i "s/^listen_addresses = .*/listen_addresses = \[\'0.0.0.0:$DNSPORT\'\]/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^dnscrypt_servers = .*/dnscrypt_servers = false/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^doh_servers = .*/doh_servers = true/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^socks4.*/socks5\t127.0.0.1 1080/g" /etc/proxychains/proxychains.conf
ADD run.sh /run.sh
ADD proxy-ltx.sh /proxy-ltx.sh
ADD proxy-ltt.sh /proxy-ltt.sh
ADD proxy-lttw.sh /proxy-lttw.sh
ADD proxy-mtt.sh /proxy-mtt.sh
ADD proxy-mttw.sh /proxy-mttw.sh
ADD proxy-ttt.sh /proxy-ttt.sh
ADD proxy-tttw.sh /proxy-tttw.sh
ADD status.sh /status.sh
RUN chmod 755 /*.sh
ENTRYPOINT ["/run.sh"]

41
Dockerfile.arm Normal file
View File

@@ -0,0 +1,41 @@
FROM arm32v6/golang:1.16-alpine as builder
ARG XRAYVER='v1.4.2'
RUN apk add --no-cache bash git build-base
WORKDIR /go/src/XTLS/Xray-core
RUN git clone https://github.com/XTLS/Xray-core.git . && \
git checkout ${XRAYVER} && \
go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
FROM arm32v6/alpine:3.14
COPY --from=builder /go/src/XTLS/Xray-core/xray /usr/local/bin/
RUN apk update && apk add bash openssl curl jq moreutils \
bind-tools whois dnscrypt-proxy ca-certificates proxychains-ng npm
RUN npm config set unsafe-perm true
RUN npm install -g qrcode-terminal
ENV DNSPORT="53"
RUN sed -i "s/^listen_addresses = .*/listen_addresses = \[\'0.0.0.0:$DNSPORT\'\]/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^dnscrypt_servers = .*/dnscrypt_servers = false/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^doh_servers = .*/doh_servers = true/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^socks4.*/socks5\t127.0.0.1 1080/g" /etc/proxychains/proxychains.conf
ADD run.sh /run.sh
ADD proxy-ltx.sh /proxy-ltx.sh
ADD proxy-ltt.sh /proxy-ltt.sh
ADD proxy-lttw.sh /proxy-lttw.sh
ADD proxy-mtt.sh /proxy-mtt.sh
ADD proxy-mttw.sh /proxy-mttw.sh
ADD proxy-ttt.sh /proxy-ttt.sh
ADD proxy-tttw.sh /proxy-tttw.sh
ADD status.sh /status.sh
RUN chmod 755 /*.sh
ENTRYPOINT ["/run.sh"]

41
Dockerfile.arm64 Normal file
View File

@@ -0,0 +1,41 @@
FROM arm64v8/golang:1.16-alpine as builder
ARG XRAYVER='v1.4.2'
RUN apk add --no-cache bash git build-base
WORKDIR /go/src/XTLS/Xray-core
RUN git clone https://github.com/XTLS/Xray-core.git . && \
git checkout ${XRAYVER} && \
go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
FROM arm64v8/alpine:3.14
COPY --from=builder /go/src/XTLS/Xray-core/xray /usr/local/bin/
RUN apk update && apk add bash openssl curl jq moreutils \
bind-tools whois dnscrypt-proxy ca-certificates proxychains-ng npm
RUN npm config set unsafe-perm true
RUN npm install -g qrcode-terminal
ENV DNSPORT="53"
RUN sed -i "s/^listen_addresses = .*/listen_addresses = \[\'0.0.0.0:$DNSPORT\'\]/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^dnscrypt_servers = .*/dnscrypt_servers = false/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^doh_servers = .*/doh_servers = true/g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml
RUN sed -i "s/^socks4.*/socks5\t127.0.0.1 1080/g" /etc/proxychains/proxychains.conf
ADD run.sh /run.sh
ADD proxy-ltx.sh /proxy-ltx.sh
ADD proxy-ltt.sh /proxy-ltt.sh
ADD proxy-lttw.sh /proxy-lttw.sh
ADD proxy-mtt.sh /proxy-mtt.sh
ADD proxy-mttw.sh /proxy-mttw.sh
ADD proxy-ttt.sh /proxy-ttt.sh
ADD proxy-tttw.sh /proxy-tttw.sh
ADD status.sh /status.sh
RUN chmod 755 /*.sh
ENTRYPOINT ["/run.sh"]

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Samuel Huang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

93
README.md Normal file
View File

@@ -0,0 +1,93 @@
# proxy-xray
Xray client container with SOCKS5/HTTP/DNS proxy and QR code support. Running on x86 and arm/arm64 (Raspberry Pi).
![docker-build](https://github.com/samuelhbne/proxy-xray/workflows/docker-buildx-latest/badge.svg)
## [Optional] How to build proxy-xray docker image
```shell
$ git clone https://github.com/samuelhbne/proxy-xray.git
$ cd proxy-xray
$ docker build -t samuelhbne/proxy-xray:amd64 -f Dockerfile.amd64 .
...
```
### NOTE1
- Please replace Dockerfile.amd64 with the Dockerfile.ARCH match your server accordingly. For example: Dockerfile.arm for 32bit Raspbian, Dockerfile.arm64 for 64bit Ubuntu for Raspberry Pi.
## How to start proxy-xray container
```shell
$ docker run --rm -it samuelhbne/proxy-xray:amd64
proxy-xray --<ltx|ltt|lttw|mtt|mttw|ttt|tttw|ssa|sst|stdin> [options]
--ltx <VLESS-TCP-XTLS option> uuid@xray-host:port
--ltt <VLESS-TCP-TLS option> uuid@xray-host:port
--lttw <VLESS-TCP-TLS-WS option> uuid@xray-host:port:/webpath
--mtt <VMESS-TCP-TLS option> uuid@xray-host:port
--mttw <VMESS-TCP-TLS-WS option> uuid@xray-host:port:/webpath
--ttt <TROJAN-TCP-TLS option> password@xray-host:port
--tttw <TROJAN-TCP-TLS-WS option> password@xray-host:port:/webpath
--stdin Read XRay config from stdin instead of auto generation
$ docker run --name proxy-xray -p 21080:1080 -p 65353:53/udp -p 28123:8123 -d samuelhbne/proxy-xray:amd64 --ltx bec24d96-410f-4723-8b3b-46987a1d9ed8@mydomain.duckdns.org:443
...
```
### NOTE2
- Please replace "amd64" with the arch match the current box accordingly. For example: "arm64" for AWS ARM64 platform like A1, t4g instance or 64bit Ubuntu on Raspberry Pi. "arm" for 32bit Raspbian.
- Please replace "mydomain.duckdns.org" with the Xray server hotsname you want to connect
- Please replace 21080 with the port number you want for SOCKS5 proxy TCP listerning.
- Please replace 28123 with the port number you want for HTTP proxy TCP listerning.
- Please replace 65353 with the port number you want for DNS UDP listerning.
- Please replace "bec24d96-410f-4723-8b3b-46987a1d9ed8" with the uuid you want to set for Xray server access.
## How to verify if proxy tunnel is working properly
```shell
$ curl -sSx socks5h://127.0.0.1:21080 http://ifconfig.co
12.34.56.78
$ curl -sSx http://127.0.0.1:28123 http://ifconfig.co
12.34.56.78
$ dig +short @127.0.0.1 -p 65353 twitter.com
104.244.42.193
104.244.42.129
$ docker exec -it proxy-xray proxychains whois 104.244.42.193|grep OrgId
[proxychains] config file found: /etc/proxychains/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.14
[proxychains] Strict chain ... 127.0.0.1:1080 ... whois.arin.net:43 ... OK
OrgId: TWITT
```
### NOTE3
- curl should return the VPN server address given above if SOCKS5/HTTP proxy works properly.
- dig should return resolved IP recorders of twitter.com if DNS server works properly.
- Whois should return "OrgId: TWITT". That means the IP address returned from dig query belongs to twitter.com indeed, hence untaminated.
- Whois was actually running inside the proxy container through the proxy tunnel to avoid potential access blocking.
- Please have a look over the sibling project [server-xray](https://github.com/samuelhbne/server-xray) if you'd like to set a Xray server.
## How to get the XRay QR code for mobile connection
```shell
$ docker exec -it proxy-xray /status.sh
VPS-Server: mydomain.duckdns.org
Xray-URL: vless://bec24d96-410f-4723-8b3b-46987a1d9ed8@mydomain.duckdns.org:443?security=xtls&type=tcp&flow=xtls-rprx-direct#mydomain.duckdns.org:443
```
![QR code example](https://github.com/samuelhbne/proxy-xray/blob/master/images/qr-xray.png)
## How to stop and remove the running container
```shell
$ docker stop proxy-xray
...
$ docker rm proxy-xray
...
```

58
proxy-ltt.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
usage() {
>&2 echo "Usage: proxy-ltt <uuid@domain0.com:443>"
}
if [ -z "$1" ]; then
>&2 echo "Missing options"
usage
exit 1
fi
# uuid@domain0.com:443
temp=$1
options=(`echo $temp |tr '@' ' '`)
id="${options[0]}"
temp="${options[1]}"
options=(`echo $temp |tr ':' ' '`)
host="${options[0]}"
port="${options[1]}"
if [ -z "${id}" ]; then
>&2 echo "Error: uuid undefined."
usage
exit 1
fi
if [ -z "${host}" ]; then
>&2 echo "Error: destination host undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
Jusers=`echo '{}' |jq --arg uuid "${id}" '. += {"id":$uuid, "encryption":"none", "level":0}'`
Jvnext=`echo '{}' | jq --arg host "${host}" --arg port "${port}" --argjson juser "${Jusers}" \
'. += {"address":$host, "port":($port | tonumber), "users":[$juser]}' `
JstreamSettings=`echo '{}' | jq --arg host "${host}" \
'. += {"network":"tcp", "security":"tls", "tlsSettings":{"serverName":$host}}' `
Joutbounds=`echo '{}' | jq --arg host "${host}" --argjson jvnext "${Jvnext}" --argjson jstreamSettings "${JstreamSettings}" \
'. += { "protocol":"vless", "settings":{"vnext":[$jvnext]}, "streamSettings":$jstreamSettings }' `
JibSOCKS=`echo '{}' | jq '. +={"port":1080, "listen":"0.0.0.0", "protocol":"socks", "settings":{"udp":true}}' `
JibHTTP=`echo '{}' | jq '. +={"port":8123, "listen":"0.0.0.0", "protocol":"http"}' `
jroot=`echo '{}' | jq --argjson jibsocks "${JibSOCKS}" --argjson jibhttp "${JibHTTP}" --argjson joutbounds "${Joutbounds}" \
'. += {"log":{"loglevel":"warning"}, "inbounds":[$jibsocks, $jibhttp], "outbounds":[$joutbounds]}' `
echo "$jroot"
exit 0

59
proxy-lttw.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
usage() {
>&2 echo "Usage: proxy-lttw <uuid@domain0.com:443:/websocket>"
}
if [ -z "$1" ]; then
>&2 echo "Missing options"
usage
exit 1
fi
# uuid@domain0.com:443:/websocket
temp=$1
options=(`echo $temp |tr '@' ' '`)
id="${options[0]}"
temp="${options[1]}"
options=(`echo $temp |tr ':' ' '`)
host="${options[0]}"
port="${options[1]}"
path="${options[2]}"
if [ -z "${id}" ]; then
>&2 echo "Error: uuid undefined."
usage
exit 1
fi
if [ -z "${host}" ]; then
>&2 echo "Error: destination host undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
Jusers=`echo '{}' |jq --arg uuid "${id}" '. += {"id":$uuid, "encryption":"none", "level":0}'`
Jvnext=`echo '{}' | jq --arg host "${host}" --arg port "${port}" --argjson juser "${Jusers}" \
'. += {"address":$host, "port":($port | tonumber), "users":[$juser]}' `
JstreamSettings=`echo '{}' | jq --arg host "${host}" --arg path "${path}" \
'. += {"network":"ws", "security":"tls", "tlsSettings":{"serverName":$host}, "wsSettings":{"path":$path}}' `
Joutbounds=`echo '{}' | jq --arg host "${host}" --argjson jvnext "${Jvnext}" --argjson jstreamSettings "${JstreamSettings}" \
'. += { "protocol":"vless", "settings":{"vnext":[$jvnext]}, "streamSettings":$jstreamSettings }' `
JibSOCKS=`echo '{}' | jq '. +={"port":1080, "listen":"0.0.0.0", "protocol":"socks", "settings":{"udp":true}}' `
JibHTTP=`echo '{}' | jq '. +={"port":8123, "listen":"0.0.0.0", "protocol":"http"}' `
jroot=`echo '{}' | jq --argjson jibsocks "${JibSOCKS}" --argjson jibhttp "${JibHTTP}" --argjson joutbounds "${Joutbounds}" \
'. += {"log":{"loglevel":"warning"}, "inbounds":[$jibsocks, $jibhttp], "outbounds":[$joutbounds]}' `
echo "$jroot"
exit 0

58
proxy-ltx.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
usage() {
>&2 echo "Usage: proxy-ltx <uuid@domain0.com:443>"
}
if [ -z "$1" ]; then
>&2 echo "Missing options"
usage
exit 1
fi
# uuid@domain0.com:443
temp=$1
options=(`echo $temp |tr '@' ' '`)
id="${options[0]}"
temp="${options[1]}"
options=(`echo $temp |tr ':' ' '`)
host="${options[0]}"
port="${options[1]}"
if [ -z "${id}" ]; then
>&2 echo "Error: uuid undefined."
usage
exit 1
fi
if [ -z "${host}" ]; then
>&2 echo "Error: destination host undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
Jusers=`echo '{}' |jq --arg uuid "${id}" '. += {"id":$uuid, "flow":"xtls-rprx-direct", "encryption":"none", "level":0}'`
Jvnext=`echo '{}' | jq --arg host "${host}" --arg port "${port}" --argjson juser "${Jusers}" \
'. += {"address":$host, "port":($port | tonumber), "users":[$juser]}' `
JstreamSettings=`echo '{}' | jq --arg host "${host}" \
'. += {"network":"tcp", "security":"xtls", "xtlsSettings":{"serverName":$host}}' `
Joutbounds=`echo '{}' | jq --arg host "${host}" --argjson jvnext "${Jvnext}" --argjson jstreamSettings "${JstreamSettings}" \
'. += { "protocol":"vless", "settings":{"vnext":[$jvnext]}, "streamSettings":$jstreamSettings }' `
JibSOCKS=`echo '{}' | jq '. +={"port":1080, "listen":"0.0.0.0", "protocol":"socks", "settings":{"udp":true}}' `
JibHTTP=`echo '{}' | jq '. +={"port":8123, "listen":"0.0.0.0", "protocol":"http"}' `
jroot=`echo '{}' | jq --argjson jibsocks "${JibSOCKS}" --argjson jibhttp "${JibHTTP}" --argjson joutbounds "${Joutbounds}" \
'. += {"log":{"loglevel":"warning"}, "inbounds":[$jibsocks, $jibhttp], "outbounds":[$joutbounds]}' `
echo "$jroot"
exit 0

65
proxy-mtt.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/bin/bash
usage() {
>&2 echo "Usage: proxy-mtt <uuid@domain0.com:443>"
}
if [ -z "$1" ]; then
>&2 echo "Missing options"
usage
exit 1
fi
# password:method@domain0.com:443/websocket
temp=$1
options=(`echo $temp |tr '@' ' '`)
id="${options[0]}"
temp="${options[1]}"
options=(`echo $temp |tr '/' ' '`)
path="${options[1]}"
temp="${options[0]}"
options=(`echo $temp |tr ':' ' '`)
host="${options[0]}"
port="${options[1]}"
temp=$id
options=(`echo $temp |tr ':' ' '`)
passwd="${options[0]}"
method="${options[2]}"
if [ -z "${id}" ]; then
>&2 echo "Error: uuid undefined."
usage
exit 1
fi
if [ -z "${host}" ]; then
>&2 echo "Error: destination host undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
Jusers=`echo '{}' |jq --arg uuid "${id}" '. += {"id":$uuid, "encryption":"none", "level":0}'`
Jvnext=`echo '{}' | jq --arg host "${host}" --arg port "${port}" --argjson juser "${Jusers}" \
'. += {"address":$host, "port":($port | tonumber), "users":[$juser]}' `
JstreamSettings=`echo '{}' | jq --arg host "${host}" \
'. += {"network":"tcp", "security":"tls", "tlsSettings":{"serverName":$host}}' `
Joutbounds=`echo '{}' | jq --arg host "${host}" --argjson jvnext "${Jvnext}" --argjson jstreamSettings "${JstreamSettings}" \
'. += { "protocol":"vmess", "settings":{"vnext":[$jvnext]}, "streamSettings":$jstreamSettings }' `
JibSOCKS=`echo '{}' | jq '. +={"port":1080, "listen":"0.0.0.0", "protocol":"socks", "settings":{"udp":true}}' `
JibHTTP=`echo '{}' | jq '. +={"port":8123, "listen":"0.0.0.0", "protocol":"http"}' `
jroot=`echo '{}' | jq --argjson jibsocks "${JibSOCKS}" --argjson jibhttp "${JibHTTP}" --argjson joutbounds "${Joutbounds}" \
'. += {"log":{"loglevel":"warning"}, "inbounds":[$jibsocks, $jibhttp], "outbounds":[$joutbounds]}' `
echo "$jroot"
exit 0

59
proxy-mttw.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
usage() {
>&2 echo "Usage: proxy-mttw <uuid@domain0.com:443:/websocket>"
}
if [ -z "$1" ]; then
>&2 echo "Missing options"
usage
exit 1
fi
# uuid@domain0.com:443:/websocket
temp=$1
options=(`echo $temp |tr '@' ' '`)
id="${options[0]}"
temp="${options[1]}"
options=(`echo $temp |tr ':' ' '`)
host="${options[0]}"
port="${options[1]}"
path="${options[2]}"
if [ -z "${id}" ]; then
>&2 echo "Error: uuid undefined."
usage
exit 1
fi
if [ -z "${host}" ]; then
>&2 echo "Error: destination host undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
Jusers=`echo '{}' |jq --arg uuid "${id}" '. += {"id":$uuid, "encryption":"none", "level":0}'`
Jvnext=`echo '{}' | jq --arg host "${host}" --arg port "${port}" --argjson juser "${Jusers}" \
'. += {"address":$host, "port":($port | tonumber), "users":[$juser]}' `
JstreamSettings=`echo '{}' | jq --arg host "${host}" --arg path "${path}" \
'. += {"network":"ws", "security":"tls", "tlsSettings":{"serverName":$host}, "wsSettings":{"path":$path}}' `
Joutbounds=`echo '{}' | jq --arg host "${host}" --argjson jvnext "${Jvnext}" --argjson jstreamSettings "${JstreamSettings}" \
'. += { "protocol":"vmess", "settings":{"vnext":[$jvnext]}, "streamSettings":$jstreamSettings }' `
JibSOCKS=`echo '{}' | jq '. +={"port":1080, "listen":"0.0.0.0", "protocol":"socks", "settings":{"udp":true}}' `
JibHTTP=`echo '{}' | jq '. +={"port":8123, "listen":"0.0.0.0", "protocol":"http"}' `
jroot=`echo '{}' | jq --argjson jibsocks "${JibSOCKS}" --argjson jibhttp "${JibHTTP}" --argjson joutbounds "${Joutbounds}" \
'. += {"log":{"loglevel":"warning"}, "inbounds":[$jibsocks, $jibhttp], "outbounds":[$joutbounds]}' `
echo "$jroot"
exit 0

62
proxy-ttt.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/bin/bash
usage() {
>&2 echo "Usage: proxy-ttt <uuid@domain0.com:443>"
}
if [ -z "$1" ]; then
>&2 echo "Missing options"
usage
exit 1
fi
# password:method@domain0.com:443:/websocket
temp=$1
options=(`echo $temp |tr '@' ' '`)
id="${options[0]}"
temp="${options[1]}"
options=(`echo $temp |tr ':' ' '`)
host="${options[0]}"
port="${options[1]}"
path="${options[2]}"
temp=$id
options=(`echo $temp |tr ':' ' '`)
passwd="${options[0]}"
method="${options[1]}"
if [ -z "${passwd}" ]; then
>&2 echo "Error: passwd undefined."
usage
exit 1
fi
if [ -z "${host}" ]; then
>&2 echo "Error: destination host undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
Jservers=`echo '{}' | jq --arg host "${host}" --arg port "${port}" --arg passwd "${passwd}" \
'. += {"address":$host, "port":($port | tonumber), "password":$passwd}' `
JstreamSettings=`echo '{}' | jq --arg host "${host}" \
'. += {"network":"tcp", "security":"tls", "tlsSettings":{"serverName":$host}}' `
Joutbounds=`echo '{}' | jq --arg host "${host}" --argjson jservers "${Jservers}" --argjson jstreamSettings "${JstreamSettings}" \
'. += { "protocol":"trojan", "settings":{"servers":[$jservers]}, "streamSettings":$jstreamSettings }' `
JibSOCKS=`echo '{}' | jq '. +={"port":1080, "listen":"0.0.0.0", "protocol":"socks", "settings":{"udp":true}}' `
JibHTTP=`echo '{}' | jq '. +={"port":8123, "listen":"0.0.0.0", "protocol":"http"}' `
jroot=`echo '{}' | jq --argjson jibsocks "${JibSOCKS}" --argjson jibhttp "${JibHTTP}" --argjson joutbounds "${Joutbounds}" \
'. += {"log":{"loglevel":"warning"}, "inbounds":[$jibsocks, $jibhttp], "outbounds":[$joutbounds]}' `
echo "$jroot"
exit 0

62
proxy-tttw.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/bin/bash
usage() {
>&2 echo "Usage: proxy-tttw <uuid@domain0.com:443:/websocket>"
}
if [ -z "$1" ]; then
>&2 echo "Missing options"
usage
exit 1
fi
# password:method@domain0.com:443:/websocket
temp=$1
options=(`echo $temp |tr '@' ' '`)
id="${options[0]}"
temp="${options[1]}"
options=(`echo $temp |tr ':' ' '`)
host="${options[0]}"
port="${options[1]}"
path="${options[2]}"
temp=$id
options=(`echo $temp |tr ':' ' '`)
passwd="${options[0]}"
method="${options[1]}"
if [ -z "${passwd}" ]; then
>&2 echo "Error: passwd undefined."
usage
exit 1
fi
if [ -z "${host}" ]; then
>&2 echo "Error: destination host undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
Jservers=`echo '{}' | jq --arg host "${host}" --arg port "${port}" --arg passwd "${passwd}" \
'. += {"address":$host, "port":($port | tonumber), "password":$passwd}' `
JstreamSettings=`echo '{}' | jq --arg host "${host}" --arg path "${path}" \
'. += {"network":"ws", "security":"tls", "tlsSettings":{"serverName":$host}, "wsSettings":{"path":$path}}' `
Joutbounds=`echo '{}' | jq --arg host "${host}" --argjson jservers "${Jservers}" --argjson jstreamSettings "${JstreamSettings}" \
'. += { "protocol":"trojan", "settings":{"servers":[$jservers]}, "streamSettings":$jstreamSettings }' `
JibSOCKS=`echo '{}' | jq '. +={"port":1080, "listen":"0.0.0.0", "protocol":"socks", "settings":{"udp":true}}' `
JibHTTP=`echo '{}' | jq '. +={"port":8123, "listen":"0.0.0.0", "protocol":"http"}' `
jroot=`echo '{}' | jq --argjson jibsocks "${JibSOCKS}" --argjson jibhttp "${JibHTTP}" --argjson joutbounds "${Joutbounds}" \
'. += {"log":{"loglevel":"warning"}, "inbounds":[$jibsocks, $jibhttp], "outbounds":[$joutbounds]}' `
echo "$jroot"
exit 0

75
run.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/bash
DIR=`dirname $0`
DIR="$(cd $DIR; pwd)"
XCONF=/tmp/proxy-xray.json
usage() {
echo "proxy-xray --<ltx|ltt|lttw|mtt|mttw|ttt|tttw|ssa|sst|stdin> [options]"
echo " --ltx <VLESS-TCP-XTLS option> uuid@xray-host:port"
echo " --ltt <VLESS-TCP-TLS option> uuid@xray-host:port"
echo " --lttw <VLESS-TCP-TLS-WS option> uuid@xray-host:port:/webpath"
echo " --mtt <VMESS-TCP-TLS option> uuid@xray-host:port"
echo " --mttw <VMESS-TCP-TLS-WS option> uuid@xray-host:port:/webpath"
echo " --ttt <TROJAN-TCP-TLS option> password@xray-host:port"
echo " --tttw <TROJAN-TCP-TLS-WS option> password@xray-host:port:/webpath"
# echo " --ssa <Shadowsocks-AEAD option> password:method@xray-host:port"
# echo " --sst <Shadowsocks-TCP option> password:method@xray-host:port"
echo " --stdin Read XRay config from stdin instead of auto generation"
}
TEMP=`getopt -o d --long ltx:,ltt:,lttw:,mtt:,mttw:,ttt:,tttw:,ssa:,sst:stdin,debug -n "$0" -- $@`
if [ $? != 0 ] ; then usage; exit 1 ; fi
eval set -- "$TEMP"
while true ; do
case "$1" in
--ltx|--ltt|--lttw|--mtt|--mttw|--ttt|--tttw|--ssa|--sst)
subcmd=`echo "$1"|tr -d "\-\-"`
echo "$DIR/proxy-${subcmd}.sh $2 >$XCONF"
$DIR/proxy-${subcmd}.sh $2 >$XCONF
if [ $? != 0 ]; then
echo "${subcmd} Config failed: $DIR/proxy-${subcmd}.sh $2"
exit 2
else
XRAY=1
fi
shift 2
;;
--stdin)
STDINCONF=1
shift 1
;;
-d|--debug)
DEBUG=1
shift 1
;;
--)
shift
break
;;
*)
usage;
exit 1
;;
esac
done
/usr/bin/dnscrypt-proxy -config /etc/dnscrypt-proxy/dnscrypt-proxy.toml &
if [ "${STDINCONF}" = "1" ]; then
exec /usr/local/bin/xray
else
if [ "${XRAY}" = "1" ]; then
if [ "${DEBUG}" = "1" ]; then
cat $XCONF |jq '.log.loglevel |="debug"' |sponge $XCONF
echo
cat $XCONF
echo
fi
exec /usr/local/bin/xray -c $XCONF
else
usage
exit 1
fi
fi

76
status.sh Executable file
View File

@@ -0,0 +1,76 @@
#!/bin/bash
XCONF=/tmp/proxy-xray.json
urlencode() {
# urlencode <string>
old_lc_collate=$LC_COLLATE
LC_COLLATE=C
local length="${#1}"
for (( i = 0; i < length; i++ )); do
local c="${1:$i:1}"
case $c in
[a-zA-Z0-9.~_-]) printf '%s' "$c" ;;
*) printf '%%%02X' "'$c" ;;
esac
done
LC_COLLATE=$old_lc_collate
}
PROTOCOL=`cat $XCONF | jq -r '.outbounds[0].protocol'`
case "${PROTOCOL}" in
vless)
XHOST=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].address'`
XPORT=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].port'`
WPATH=`cat $XCONF | jq -r '.outbounds[0].streamSettings.wsSettings.path'`
UUID=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].users[0].id'`
XENCRYPT=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].users[0].encryption'`
XSEC=`cat $XCONF | jq -r '.outbounds[0].streamSettings.security'`
XNETWORK=`cat $XCONF | jq -r '.outbounds[0].streamSettings.network'`
XFLOW=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].users[0].flow'`
XURL="${PROTOCOL}://${UUID}@${XHOST}:${XPORT}?security=${XSEC}&type=${XNETWORK}"
if [ "${XFLOW}" != "null" ]; then XURL="${XURL}&flow=${XFLOW}"; fi
if [ "${WPATH}" != "null" ]; then XURL="${XURL}&path=$(urlencode ${WPATH})"; fi
XURL="${XURL}#${XHOST}:${XPORT}"
;;
vmess)
XHOST=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].address'`
XPORT=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].port'`
WPATH=`cat $XCONF | jq -r '.outbounds[0].streamSettings.wsSettings.path'`
UUID=`cat $XCONF | jq -r '.outbounds[0].settings.vnext[0].users[0].id'`
XNETWORK=`cat $XCONF | jq -r '.outbounds[0].streamSettings.network'`
JXURL=`echo '{}' |jq --arg xhost "${XHOST}" --arg xport "${XPORT}" '. += {"v":2, "add":$xhost, "port":$xport}' `
JXURL=`echo ${JXURL} | jq --arg uuid "${UUID}" --arg network "${XNETWORK}" '. += {"id":$uuid, "net":$network}' `
JXURL=`echo ${JXURL} | jq '. += {"scy":"auto", "tls":"tls"}' `
if [ "${WPATH}" != "null" ]; then
JXURL=`echo ${JXURL} | jq --arg wpath "${WPATH}" '. += {"path":$wpath}' `
fi
JXURL=`echo ${JXURL} |jq --arg xhost "${XHOST}" --arg xport "${XPORT}" '. += {"ps":($xhost+":"+$xport)}' `
XURL=`echo $JXURL|jq -c|base64|tr -d '\n'`
XURL="${PROTOCOL}://${XURL}"
;;
trojan)
XHOST=`cat $XCONF | jq -r '.outbounds[0].settings.servers[0].address'`
XPORT=`cat $XCONF | jq -r '.outbounds[0].settings.servers[0].port'`
XPASS=`cat $XCONF | jq -r '.outbounds[0].settings.servers[0].password'`
WPATH=`cat $XCONF | jq -r '.outbounds[0].streamSettings.wsSettings.path'`
XURL="${PROTOCOL}://${XPASS}@${XHOST}:${XPORT}"
if [ "${WPATH}" != "null" ]; then
XURL="${XURL}/?type=ws&path=$(urlencode ${WPATH})"
fi
XURL="${XURL}#${XHOST}:${XPORT}"
;;
*)
echo "Unknown protocol: ${PROTOCOL}"
echo "Abort"
exit 2
;;
esac
echo "VPS-Server: ${XHOST}"
echo "Xray-URL: ${XURL}"
qrcode-terminal "${XURL}"
exit 0