mirror of
https://github.com/samuelhbne/server-xray.git
synced 2025-12-16 20:07:06 +03:00
Init import
This commit is contained in:
32
Dockerfile.amd64
Normal file
32
Dockerfile.amd64
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
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 nginx openssl curl socat jq moreutils
|
||||||
|
RUN cd /root; curl -sSL "https://github.com/acmesh-official/acme.sh/archive/refs/tags/2.9.0.tar.gz"|tar zxvf -
|
||||||
|
RUN cd /root; mv acme.sh-2.9.0 .acme.sh
|
||||||
|
|
||||||
|
ADD run.sh /run.sh
|
||||||
|
ADD server-ltx.sh /server-ltx.sh
|
||||||
|
ADD server-ltt.sh /server-ltt.sh
|
||||||
|
ADD server-lttw.sh /server-lttw.sh
|
||||||
|
ADD server-mtt.sh /server-mtt.sh
|
||||||
|
ADD server-mttw.sh /server-mttw.sh
|
||||||
|
ADD server-ttt.sh /server-ttt.sh
|
||||||
|
ADD server-tttw.sh /server-tttw.sh
|
||||||
|
|
||||||
|
RUN chmod 755 /*.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/run.sh"]
|
||||||
32
Dockerfile.arm
Normal file
32
Dockerfile.arm
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
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 nginx openssl curl socat jq moreutils
|
||||||
|
RUN cd /root; curl -sSL "https://github.com/acmesh-official/acme.sh/archive/refs/tags/2.9.0.tar.gz"|tar zxvf -
|
||||||
|
RUN cd /root; mv acme.sh-2.9.0 .acme.sh
|
||||||
|
|
||||||
|
ADD run.sh /run.sh
|
||||||
|
ADD server-ltx.sh /server-ltx.sh
|
||||||
|
ADD server-ltt.sh /server-ltt.sh
|
||||||
|
ADD server-lttw.sh /server-lttw.sh
|
||||||
|
ADD server-mtt.sh /server-mtt.sh
|
||||||
|
ADD server-mttw.sh /server-mttw.sh
|
||||||
|
ADD server-ttt.sh /server-ttt.sh
|
||||||
|
ADD server-tttw.sh /server-tttw.sh
|
||||||
|
|
||||||
|
RUN chmod 755 /*.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/run.sh"]
|
||||||
32
Dockerfile.arm64
Normal file
32
Dockerfile.arm64
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
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 nginx openssl curl socat jq moreutils
|
||||||
|
RUN cd /root; curl -sSL "https://github.com/acmesh-official/acme.sh/archive/refs/tags/2.9.0.tar.gz"|tar zxvf -
|
||||||
|
RUN cd /root; mv acme.sh-2.9.0 .acme.sh
|
||||||
|
|
||||||
|
ADD run.sh /run.sh
|
||||||
|
ADD server-ltx.sh /server-ltx.sh
|
||||||
|
ADD server-ltt.sh /server-ltt.sh
|
||||||
|
ADD server-lttw.sh /server-lttw.sh
|
||||||
|
ADD server-mtt.sh /server-mtt.sh
|
||||||
|
ADD server-mttw.sh /server-mttw.sh
|
||||||
|
ADD server-ttt.sh /server-ttt.sh
|
||||||
|
ADD server-tttw.sh /server-tttw.sh
|
||||||
|
|
||||||
|
RUN chmod 755 /*.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/run.sh"]
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal 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.
|
||||||
89
README.md
Normal file
89
README.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# server-xray
|
||||||
|
|
||||||
|
Yet another unofficial [xray](https://github.com/XTLS/Xray-core) server container with x86 and arm/arm64 (Raspberry Pi) support.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## [Optional] How to build server-xray docker image
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ git clone https://github.com/samuelhbne/server-xray.git
|
||||||
|
$ cd server-xray
|
||||||
|
$ docker build -t samuelhbne/server-xray:amd64 -f Dockerfile.amd64 .
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### NOTE1
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
## How to start the container
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ docker run --rm -it samuelhbne/server-xray:amd64
|
||||||
|
server-xray --<ltx|ltt|lttw|mtt|mttw|ttt> <options> [-r|--request-domain <domain-name>] [-c|--cert-path <cert-path-root>] [-k|--hook <hook-url>]
|
||||||
|
-k|--hook <hook-url> [Optional] DDNS update or notifing URL to be hit. Multiple allowed
|
||||||
|
-r|--request-domain <domain-name> [Optional] Domain name to request for letsencrypt cert. Multiple allowed
|
||||||
|
-c|--cert-path <cert-path-root> [Optional] Reading TLS certs from folder <cert-path-root>/<domain-name>/. Multiple allowed
|
||||||
|
--ltx <VLESS-TCP-XTLS option> p=1443,d=domain0.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]]
|
||||||
|
--ltt <VLESS-TCP-TLS option> p=2443,d=domain1.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]]
|
||||||
|
--lttw <VLESS-TCP-TLS-WS option> p=3443,d=domain2.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]],w=/webpath
|
||||||
|
--mtt <VMESS-TCP-TLS option> p=4443,d=domain3.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]]
|
||||||
|
--mttw <VMESS-TCP-TLS-WS option> p=5443,d=domain4.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]],w=/webpath
|
||||||
|
--ttt <TROJAN-TCP-TLS option> p=6443,d=domain5.com,u=passwd[:email][,f=[fallback-host]:fb-port:[fb-path]]
|
||||||
|
--tttw <TROJAN-TCP-TLS-WS option> p=7443,d=domain5.com,u=passwd[:email][,f=[fallback-host]:fb-port:[fb-path]],w=/webpath
|
||||||
|
--stdin Read XRay config from stdin instead of auto generation
|
||||||
|
|
||||||
|
$ docker run --name server-xray -p 8443:443 -d samuelhbne/server-xray:amd64 --ltx p=443,d=mydomain.duckdns.org,u=bec24d96-410f-4723-8b3b-46987a1d9ed8,f=:80 -k https://duckdns.org/update/mydomain/c9711c65-db21-4f8c-a790-2c32c93bde8c -r mydomain.duckdns.org
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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 "8443" with the TCP port number you want to listen.
|
||||||
|
- Please replace "bec24d96-410f-4723-8b3b-46987a1d9ed8" with the uuid you want to set for Xray client auth.
|
||||||
|
- Please replace mydomain.duckdns.org with the domain-name for Letsencrypt cert request.
|
||||||
|
- You can optionally assign a HOOK-URL to update the DDNS domain-name pointing to the current server public IP address.
|
||||||
|
|
||||||
|
## How to verify if server-xray is running properly
|
||||||
|
|
||||||
|
Try to connect the server from v2ray compatible mobile app like [v2rayNG](https://github.com/2dust/v2rayNG) for Android or [Shadowrocket](https://apps.apple.com/us/app/shadowrocket/id932747118) for iOS with the host-name, port, UUID etc. set above. Or verify it from Ubuntu / Debian / Raspbian client host follow the instructions below.
|
||||||
|
|
||||||
|
### Please run the following instructions from Ubuntu / Debian / Raspbian client host for verifying
|
||||||
|
|
||||||
|
```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 1080:1080 -p 65353:53/udp -p 8123:8123 -d samuelhbne/proxy-xray:amd64 --ltx bec24d96-410f-4723-8b3b-46987a1d9ed8@nvda.duckdns.org:8443
|
||||||
|
...
|
||||||
|
|
||||||
|
$ curl -sSx socks5h://127.0.0.1:1080 http://ifconfig.co
|
||||||
|
12.34.56.78
|
||||||
|
```
|
||||||
|
|
||||||
|
### NOTE4
|
||||||
|
|
||||||
|
- First we ran proxy-xray as SOCKS5 proxy that tunneling traffic through your Xray server.
|
||||||
|
- Then launching curl with client-IP address query through the proxy.
|
||||||
|
- This query was sent through your server with server-xray running.
|
||||||
|
- You should get the public IP address of your server with server-xray running if all good.
|
||||||
|
- Please have a look over the sibling project [proxy-xray](https://github.com/samuelhbne/proxy-xray) for more details.
|
||||||
|
|
||||||
|
## How to stop and remove the running container
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ docker stop server-xray
|
||||||
|
...
|
||||||
|
$ docker rm server-xray
|
||||||
|
...
|
||||||
|
```
|
||||||
132
run.sh
Executable file
132
run.sh
Executable file
@@ -0,0 +1,132 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DIR=`dirname $0`
|
||||||
|
DIR="$(cd $DIR; pwd)"
|
||||||
|
XCONF=/tmp/server-xray.json
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "server-xray --<ltx|ltt|lttw|mtt|mttw|ttt> <options> [-r|--request-domain <domain-name>] [-c|--cert-path <cert-path-root>] [-k|--hook <hook-url>]"
|
||||||
|
echo " -k|--hook <hook-url> [Optional] DDNS update or notifing URL to be hit. Multiple allowed"
|
||||||
|
echo " -r|--request-domain <domain-name> [Optional] Domain name to request for letsencrypt cert. Multiple allowed"
|
||||||
|
echo " -c|--cert-path <cert-path-root> [Optional] Reading TLS certs from folder <cert-path-root>/<domain-name>/. Multiple allowed"
|
||||||
|
echo " --ltx <VLESS-TCP-XTLS option> p=1443,d=domain0.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]]"
|
||||||
|
echo " --ltt <VLESS-TCP-TLS option> p=2443,d=domain1.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]]"
|
||||||
|
echo " --lttw <VLESS-TCP-TLS-WS option> p=3443,d=domain2.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]],w=/webpath"
|
||||||
|
echo " --mtt <VMESS-TCP-TLS option> p=4443,d=domain3.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]]"
|
||||||
|
echo " --mttw <VMESS-TCP-TLS-WS option> p=5443,d=domain4.com,u=uuid[:level[:email]][,f=[fallback-host]:fb-port:[fb-path]],w=/webpath"
|
||||||
|
echo " --ttt <TROJAN-TCP-TLS option> p=6443,d=domain5.com,u=passwd[:email][,f=[fallback-host]:fb-port:[fb-path]]"
|
||||||
|
echo " --tttw <TROJAN-TCP-TLS-WS option> p=7443,d=domain5.com,u=passwd[:email][,f=[fallback-host]:fb-port:[fb-path]],w=/webpath"
|
||||||
|
# echo " --ssa <Shadowsocks-AEAD option> port=8443,user=password1:method1[,user=password2:method2]"
|
||||||
|
# echo " --sst <Shadowsocks-TCP option> port=9443,user=passwd,method=xxxx"
|
||||||
|
echo " --stdin Read XRay config from stdin instead of auto generation"
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMP=`getopt -o k:r:c:d --long hook:,request-domain:,cert-path:,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
|
||||||
|
-k|--hook)
|
||||||
|
HOOKURL+=("$2")
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-r|--request-domain)
|
||||||
|
CERTDOMAIN+=("$2")
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-c|--cert-path)
|
||||||
|
CERTPATH+="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-d|--debug)
|
||||||
|
DEBUG=1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--ltx|--ltt|--lttw|--mtt|--mttw|--ttt|--tttw)
|
||||||
|
SVC=`echo $1|tr -d '\-\-'`
|
||||||
|
SVCMD+=("$DIR/server-${SVC}.sh $2")
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--stdin)
|
||||||
|
STDINCONF=1
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Get: $1"
|
||||||
|
usage;
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "${HOOKURL}" ]; then
|
||||||
|
for URL in "${HOOKURL[@]}"
|
||||||
|
do
|
||||||
|
echo "curl -sSL $URL"
|
||||||
|
curl -sSL "$URL"
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
echo "Wait 10s for hook updates..."
|
||||||
|
sleep 10
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${CERTDOMAIN}" ]; then
|
||||||
|
for DOMAIN in "${CERTDOMAIN[@]}"
|
||||||
|
do
|
||||||
|
TRY=0
|
||||||
|
while [ ! -f "/root/.acme.sh/${DOMAIN}/fullchain.cer" ] || [ ! -f "/root/.acme.sh/${DOMAIN}/${DOMAIN}.key" ]
|
||||||
|
do
|
||||||
|
echo "Requesting TLS cert for ${DOMAIN} ..."
|
||||||
|
/root/.acme.sh/acme.sh --issue --standalone -d ${DOMAIN}
|
||||||
|
((TRY++))
|
||||||
|
if [ "${TRY}" -ge 3 ]; then
|
||||||
|
echo "Requesting TLS cert for ${DOMAIN} failed. Check log please."
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
echo "Wait 10 seconds before checking cert again..."
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo '{"log":{"loglevel":"warning"}, "inbounds":[], "outbounds":[{"protocol":"freedom"}]}' |jq .|sponge $XCONF
|
||||||
|
|
||||||
|
xopt="xconf=$XCONF"
|
||||||
|
CERTPATH+=("/root/.acme.sh")
|
||||||
|
for cp in "${CERTPATH[@]}"
|
||||||
|
do
|
||||||
|
xopt="$xopt,certpath=$cp"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "${SVCMD}" ]; then
|
||||||
|
for svcmd in "${SVCMD[@]}"
|
||||||
|
do
|
||||||
|
svcmd="$svcmd,$xopt"
|
||||||
|
$svcmd
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo
|
||||||
|
echo "Command failed: $svcmd"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
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
|
||||||
|
if [ "${STDINCONF}" = "1" ]; then
|
||||||
|
exec /usr/local/bin/xray
|
||||||
|
else
|
||||||
|
echo "Mode selection option missing."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
160
server-ltt.sh
Executable file
160
server-ltt.sh
Executable file
@@ -0,0 +1,160 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: server-ltt <xconf=xray-config-file>,<certpath=cert-path-root>,<port=443>,<domain=mydomain.com>,<user=xxx-xxx[:0[:a@mail.com]]>[,fallback=www.baidu.com:443:/html][,fallback=:2443:/websocket2]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
x|xconf)
|
||||||
|
xconf="${kv[1]}"
|
||||||
|
;;
|
||||||
|
c|certpath)
|
||||||
|
certpath+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${certpath}" ]; then
|
||||||
|
echo "Error: certpath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xconf}" ]; then
|
||||||
|
echo "Error: xconf undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
echo "Error: port undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
echo "Error: domain undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
echo "Error: user undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
XCONF=$xconf
|
||||||
|
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
|
||||||
|
|
||||||
|
for xu in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
uopt=(${xu})
|
||||||
|
uopt=(${uopt[@]})
|
||||||
|
|
||||||
|
if [ -z "${uopt[0]}" ]; then
|
||||||
|
echo "Incorrect user format: ${xu}"
|
||||||
|
echo "Correct user format: user=<uuid>[:level:email]"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962:0:me@g.cn"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962::me@g.cn"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962:0"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[1]}" ]; then
|
||||||
|
uopt[1]=0
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[2]}" ]; then
|
||||||
|
uopt[2]="nobody@g.cn"
|
||||||
|
fi
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg uid "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"id":$uid, "level":($level|tonumber), "email":$email} ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
fopt=(${fb})
|
||||||
|
fopt=(${fopt[@]})
|
||||||
|
|
||||||
|
fhost="${fopt[0]}"
|
||||||
|
fport="${fopt[1]}"
|
||||||
|
fpath="${fopt[2]}"
|
||||||
|
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
echo "Incorrect fallback format: ${fb}"
|
||||||
|
echo "Correct fallback: fallback=[host]<:port>[:path]"
|
||||||
|
echo "Like: fallback=baidu.com:443:/websocket"
|
||||||
|
echo "Like: fallback=:1443:/websocket"
|
||||||
|
echo "Like: fallback=:1443"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${fhost}" ]; then
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
fdest="${fhost}:${fport}"
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --argjson jfallback "$Jfallback" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp", "security":"tls" } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{"alpn":["http/1.1"]} } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for certroot in "${certpath[@]}"
|
||||||
|
do
|
||||||
|
if [ -f "${certroot}/${domain}/fullchain.cer" ] && [ -f "${certroot}/${domain}/${domain}.key" ]; then
|
||||||
|
fullchain="${certroot}/${domain}/fullchain.cer"
|
||||||
|
prvkey="${certroot}/${domain}/${domain}.key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
||||||
|
echo "TLS cert missing?"
|
||||||
|
echo "Abort."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.tlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
||||||
|
|sponge $XCONF
|
||||||
173
server-lttw.sh
Executable file
173
server-lttw.sh
Executable file
@@ -0,0 +1,173 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: server-lttw <xconf=xray-config-file>,<certpath=cert-path-root>,<port=443>,<domain=mydomain.com>,<user=xxx-xxx[:0[:a@mail.com]]>,<path=websocket-path>[,fallback=www.baidu.com:443:/html][,fallback=:2443:/websocket2]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
x|xconf)
|
||||||
|
xconf="${kv[1]}"
|
||||||
|
;;
|
||||||
|
c|certpath)
|
||||||
|
certpath+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
w|wpath)
|
||||||
|
wspath="${kv[1]}"
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${certpath}" ]; then
|
||||||
|
echo "Error: certpath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xconf}" ]; then
|
||||||
|
echo "Error: xconf undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
echo "Error: port undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
echo "Error: domain undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
echo "Error: user undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${wspath}" ]; then
|
||||||
|
echo "Error: wspath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
XCONF=$xconf
|
||||||
|
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
|
||||||
|
|
||||||
|
for xu in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
uopt=(${xu})
|
||||||
|
uopt=(${uopt[@]})
|
||||||
|
|
||||||
|
if [ -z "${uopt[0]}" ]; then
|
||||||
|
echo "Incorrect user format: ${xu}"
|
||||||
|
echo "Correct user format: user=<uuid>[:level:email]"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962:0:me@g.cn"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962::me@g.cn"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962:0"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[1]}" ]; then
|
||||||
|
uopt[1]=0
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[2]}" ]; then
|
||||||
|
uopt[2]="nobody@g.cn"
|
||||||
|
fi
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg uid "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"id":$uid, "level":($level|tonumber), "email":$email} ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
fopt=(${fb})
|
||||||
|
fopt=(${fopt[@]})
|
||||||
|
|
||||||
|
fhost="${fopt[0]}"
|
||||||
|
fport="${fopt[1]}"
|
||||||
|
fpath="${fopt[2]}"
|
||||||
|
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
echo "Incorrect fallback format: ${fb}"
|
||||||
|
echo "Correct fallback: fallback=[host]<:port>[:path]"
|
||||||
|
echo "Like: fallback=baidu.com:443:/websocket"
|
||||||
|
echo "Like: fallback=:1443:/websocket"
|
||||||
|
echo "Like: fallback=:1443"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${fhost}" ]; then
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
fdest="${fhost}:${fport}"
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --argjson jfallback "$Jfallback" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws", "security":"tls" } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{"alpn":["http/1.1"]} } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"wsSettings":{"path":$wspath}} ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for certroot in "${certpath[@]}"
|
||||||
|
do
|
||||||
|
if [ -f "${certroot}/${domain}/fullchain.cer" ] && [ -f "${certroot}/${domain}/${domain}.key" ]; then
|
||||||
|
fullchain="${certroot}/${domain}/fullchain.cer"
|
||||||
|
prvkey="${certroot}/${domain}/${domain}.key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
||||||
|
echo "TLS cert missing?"
|
||||||
|
echo "Abort."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.tlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
||||||
|
|sponge $XCONF
|
||||||
160
server-ltx.sh
Executable file
160
server-ltx.sh
Executable file
@@ -0,0 +1,160 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: server-ltx <xconf=xray-config-file>,<certpath=cert-path-root>,<port=443>,<domain=mydomain.com>,<user=xxx-xxx[:0[:a@mail.com]]>[,fallback=www.baidu.com:443:/html][,fallback=:2443:/websocket2]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
x|xconf)
|
||||||
|
xconf="${kv[1]}"
|
||||||
|
;;
|
||||||
|
c|certpath)
|
||||||
|
certpath+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${certpath}" ]; then
|
||||||
|
echo "Error: certpath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xconf}" ]; then
|
||||||
|
echo "Error: xconf undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
echo "Error: port undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
echo "Error: domain undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
echo "Error: user undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
XCONF=$xconf
|
||||||
|
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
|
||||||
|
|
||||||
|
for xu in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
uopt=(${xu})
|
||||||
|
uopt=(${uopt[@]})
|
||||||
|
|
||||||
|
if [ -z "${uopt[0]}" ]; then
|
||||||
|
echo "Incorrect user format: ${xu}"
|
||||||
|
echo "Correct user format: user=<uuid>[:level:email]"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962:0:me@g.cn"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962::me@g.cn"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962:0"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[1]}" ]; then
|
||||||
|
uopt[1]=0
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[2]}" ]; then
|
||||||
|
uopt[2]="nobody@g.cn"
|
||||||
|
fi
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg uid "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"id":$uid, "flow":"xtls-rprx-direct", "level":($level|tonumber), "email":$email} ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
fopt=(${fb})
|
||||||
|
fopt=(${fopt[@]})
|
||||||
|
|
||||||
|
fhost="${fopt[0]}"
|
||||||
|
fport="${fopt[1]}"
|
||||||
|
fpath="${fopt[2]}"
|
||||||
|
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
echo "Incorrect fallback format: ${fb}"
|
||||||
|
echo "Correct fallback: fallback=[host]<:port>[:path]"
|
||||||
|
echo "Like: fallback=baidu.com:443:/websocket"
|
||||||
|
echo "Like: fallback=:1443:/websocket"
|
||||||
|
echo "Like: fallback=:1443"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${fhost}" ]; then
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
fdest="${fhost}:${fport}"
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --argjson jfallback "$Jfallback" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp", "security":"xtls" } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"xtlsSettings":{"alpn":["http/1.1"]} } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for certroot in "${certpath[@]}"
|
||||||
|
do
|
||||||
|
if [ -f "${certroot}/${domain}/fullchain.cer" ] && [ -f "${certroot}/${domain}/${domain}.key" ]; then
|
||||||
|
fullchain="${certroot}/${domain}/fullchain.cer"
|
||||||
|
prvkey="${certroot}/${domain}/${domain}.key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
||||||
|
echo "TLS cert missing?"
|
||||||
|
echo "Abort."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.xtlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
||||||
|
|sponge $XCONF
|
||||||
160
server-mtt.sh
Executable file
160
server-mtt.sh
Executable file
@@ -0,0 +1,160 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: server-mtt <xconf=xray-config-file>,<certpath=cert-path-root>,<port=443>,<domain=mydomain.com>,<user=xxx-xxx[:0[:a@mail.com]]>[,fallback=www.baidu.com:443:/html][,fallback=:2443:/websocket2]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
x|xconf)
|
||||||
|
xconf="${kv[1]}"
|
||||||
|
;;
|
||||||
|
c|certpath)
|
||||||
|
certpath+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${certpath}" ]; then
|
||||||
|
echo "Error: certpath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xconf}" ]; then
|
||||||
|
echo "Error: xconf undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
echo "Error: port undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
echo "Error: domain undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
echo "Error: user undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
XCONF=$xconf
|
||||||
|
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vmess", "settings":{"clients":[]}}]' |sponge $XCONF
|
||||||
|
|
||||||
|
for xu in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
uopt=(${xu})
|
||||||
|
uopt=(${uopt[@]})
|
||||||
|
|
||||||
|
if [ -z "${uopt[0]}" ]; then
|
||||||
|
echo "Incorrect user format: ${xu}"
|
||||||
|
echo "Correct user format: user=<uuid>[:level:email]"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962:0:me@g.cn"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962::me@g.cn"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962:0"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[1]}" ]; then
|
||||||
|
uopt[1]=0
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[2]}" ]; then
|
||||||
|
uopt[2]="nobody@g.cn"
|
||||||
|
fi
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg uid "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"id":$uid, "level":($level|tonumber), "email":$email} ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
fopt=(${fb})
|
||||||
|
fopt=(${fopt[@]})
|
||||||
|
|
||||||
|
fhost="${fopt[0]}"
|
||||||
|
fport="${fopt[1]}"
|
||||||
|
fpath="${fopt[2]}"
|
||||||
|
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
echo "Incorrect fallback format: ${fb}"
|
||||||
|
echo "Correct fallback: fallback=[host]<:port>[:path]"
|
||||||
|
echo "Like: fallback=baidu.com:443:/websocket"
|
||||||
|
echo "Like: fallback=:1443:/websocket"
|
||||||
|
echo "Like: fallback=:1443"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${fhost}" ]; then
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
fdest="${fhost}:${fport}"
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --argjson jfallback "$Jfallback" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp", "security":"tls" } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{"alpn":["http/1.1"]} } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for certroot in "${certpath[@]}"
|
||||||
|
do
|
||||||
|
if [ -f "${certroot}/${domain}/fullchain.cer" ] && [ -f "${certroot}/${domain}/${domain}.key" ]; then
|
||||||
|
fullchain="${certroot}/${domain}/fullchain.cer"
|
||||||
|
prvkey="${certroot}/${domain}/${domain}.key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
||||||
|
echo "TLS cert missing?"
|
||||||
|
echo "Abort."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.tlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
||||||
|
|sponge $XCONF
|
||||||
173
server-mttw.sh
Executable file
173
server-mttw.sh
Executable file
@@ -0,0 +1,173 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: server-mttw <xconf=xray-config-file>,<certpath=cert-path-root>,<port=443>,<domain=mydomain.com>,<user=xxx-xxx[:0[:a@mail.com]]>,<path=websocket-path>[,fallback=www.baidu.com:443:/html][,fallback=:2443:/websocket2]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
x|xconf)
|
||||||
|
xconf="${kv[1]}"
|
||||||
|
;;
|
||||||
|
c|certpath)
|
||||||
|
certpath+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
w|wpath)
|
||||||
|
wspath="${kv[1]}"
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${certpath}" ]; then
|
||||||
|
echo "Error: certpath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xconf}" ]; then
|
||||||
|
echo "Error: xconf undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
echo "Error: port undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
echo "Error: domain undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
echo "Error: user undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${wspath}" ]; then
|
||||||
|
echo "Error: wspath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
XCONF=$xconf
|
||||||
|
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vmess", "settings":{"clients":[]}}]' |sponge $XCONF
|
||||||
|
|
||||||
|
for xu in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
uopt=(${xu})
|
||||||
|
uopt=(${uopt[@]})
|
||||||
|
|
||||||
|
if [ -z "${uopt[0]}" ]; then
|
||||||
|
echo "Incorrect user format: ${xu}"
|
||||||
|
echo "Correct user format: user=<uuid>[:level:email]"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962:0:me@g.cn"
|
||||||
|
echo "Like: user=805b2209-c26f-48d6-ba52-07b7d894f962::me@g.cn"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962:0"
|
||||||
|
echo "user=805b2209-c26f-48d6-ba52-07b7d894f962"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[1]}" ]; then
|
||||||
|
uopt[1]=0
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[2]}" ]; then
|
||||||
|
uopt[2]="nobody@g.cn"
|
||||||
|
fi
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg uid "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"id":$uid, "level":($level|tonumber), "email":$email} ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
fopt=(${fb})
|
||||||
|
fopt=(${fopt[@]})
|
||||||
|
|
||||||
|
fhost="${fopt[0]}"
|
||||||
|
fport="${fopt[1]}"
|
||||||
|
fpath="${fopt[2]}"
|
||||||
|
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
echo "Incorrect fallback format: ${fb}"
|
||||||
|
echo "Correct fallback: fallback=[host]<:port>[:path]"
|
||||||
|
echo "Like: fallback=baidu.com:443:/websocket"
|
||||||
|
echo "Like: fallback=:1443:/websocket"
|
||||||
|
echo "Like: fallback=:1443"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${fhost}" ]; then
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
fdest="${fhost}:${fport}"
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --argjson jfallback "$Jfallback" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws", "security":"tls" } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{"alpn":["http/1.1"]} } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"wsSettings":{"path":$wspath}} ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for certroot in "${certpath[@]}"
|
||||||
|
do
|
||||||
|
if [ -f "${certroot}/${domain}/fullchain.cer" ] && [ -f "${certroot}/${domain}/${domain}.key" ]; then
|
||||||
|
fullchain="${certroot}/${domain}/fullchain.cer"
|
||||||
|
prvkey="${certroot}/${domain}/${domain}.key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
||||||
|
echo "TLS cert missing?"
|
||||||
|
echo "Abort."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.tlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
||||||
|
|sponge $XCONF
|
||||||
155
server-ttt.sh
Executable file
155
server-ttt.sh
Executable file
@@ -0,0 +1,155 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: server-ttt <xconf=xray-config-file>,<certpath=cert-path-root>,<port=443>,<domain=mydomain.com>,<user=password[:0[:a@mail.com]]>[,fallback=www.baidu.com:443:/html][,fallback=:2443:/websocket2]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
x|xconf)
|
||||||
|
xconf="${kv[1]}"
|
||||||
|
;;
|
||||||
|
c|certpath)
|
||||||
|
certpath+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${certpath}" ]; then
|
||||||
|
echo "Error: certpath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xconf}" ]; then
|
||||||
|
echo "Error: xconf undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
echo "Error: port undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
echo "Error: domain undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
echo "Error: user undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
XCONF=$xconf
|
||||||
|
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"trojan", "settings":{"clients":[]}}]' |sponge $XCONF
|
||||||
|
|
||||||
|
for xu in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
uopt=(${xu})
|
||||||
|
uopt=(${uopt[@]})
|
||||||
|
|
||||||
|
if [ -z "${uopt[0]}" ]; then
|
||||||
|
echo "Incorrect user format: ${xu}"
|
||||||
|
echo "Correct user format: user=<password>[:email]"
|
||||||
|
echo "Like: user=trojan_pass:me@g.cn"
|
||||||
|
echo "Like: user=trojan_pass"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[1]}" ]; then
|
||||||
|
uopt[1]="nobody@g.cn"
|
||||||
|
fi
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg password "${uopt[0]}" --arg email "${uopt[1]}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"password":$password, "email":$email} ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
fopt=(${fb})
|
||||||
|
fopt=(${fopt[@]})
|
||||||
|
|
||||||
|
fhost="${fopt[0]}"
|
||||||
|
fport="${fopt[1]}"
|
||||||
|
fpath="${fopt[2]}"
|
||||||
|
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
echo "Incorrect fallback format: ${fb}"
|
||||||
|
echo "Correct fallback: fallback=[host]<:port>[:path]"
|
||||||
|
echo "Like: fallback=baidu.com:443:/websocket"
|
||||||
|
echo "Like: fallback=:1443:/websocket"
|
||||||
|
echo "Like: fallback=:1443"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${fhost}" ]; then
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
fdest="${fhost}:${fport}"
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --argjson jfallback "$Jfallback" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp", "security":"tls" } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{"alpn":["http/1.1"]} } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for certroot in "${certpath[@]}"
|
||||||
|
do
|
||||||
|
if [ -f "${certroot}/${domain}/fullchain.cer" ] && [ -f "${certroot}/${domain}/${domain}.key" ]; then
|
||||||
|
fullchain="${certroot}/${domain}/fullchain.cer"
|
||||||
|
prvkey="${certroot}/${domain}/${domain}.key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
||||||
|
echo "TLS cert missing?"
|
||||||
|
echo "Abort."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.tlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
||||||
|
|sponge $XCONF
|
||||||
168
server-tttw.sh
Executable file
168
server-tttw.sh
Executable file
@@ -0,0 +1,168 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: server-tttw <xconf=xray-config-file>,<certpath=cert-path-root>,<port=443>,<domain=mydomain.com>,<user=password[:a@mail.com]>,<path=websocket-path>[,fallback=www.baidu.com:443:/html][,fallback=:2443:/websocket2]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
x|xconf)
|
||||||
|
xconf="${kv[1]}"
|
||||||
|
;;
|
||||||
|
c|certpath)
|
||||||
|
certpath+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
w|wpath)
|
||||||
|
wspath="${kv[1]}"
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${certpath}" ]; then
|
||||||
|
echo "Error: certpath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xconf}" ]; then
|
||||||
|
echo "Error: xconf undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
echo "Error: port undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
echo "Error: domain undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
echo "Error: user undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${wspath}" ]; then
|
||||||
|
echo "Error: wspath undefined."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
XCONF=$xconf
|
||||||
|
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"trojan", "settings":{"clients":[]}}]' |sponge $XCONF
|
||||||
|
|
||||||
|
for xu in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
uopt=(${xu})
|
||||||
|
uopt=(${uopt[@]})
|
||||||
|
|
||||||
|
if [ -z "${uopt[0]}" ]; then
|
||||||
|
echo "Incorrect user format: ${xu}"
|
||||||
|
echo "Correct user format: user=<password>[:email]"
|
||||||
|
echo "Like: user=trojan_pass:me@g.cn"
|
||||||
|
echo "Like: user=trojan_pass"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${uopt[1]}" ]; then
|
||||||
|
uopt[1]="nobody@g.cn"
|
||||||
|
fi
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg password "${uopt[0]}" --arg email "${uopt[1]}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"password":$password, "email":$email} ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'
|
||||||
|
fopt=(${fb})
|
||||||
|
fopt=(${fopt[@]})
|
||||||
|
|
||||||
|
fhost="${fopt[0]}"
|
||||||
|
fport="${fopt[1]}"
|
||||||
|
fpath="${fopt[2]}"
|
||||||
|
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
echo "Incorrect fallback format: ${fb}"
|
||||||
|
echo "Correct fallback: fallback=[host]<:port>[:path]"
|
||||||
|
echo "Like: fallback=baidu.com:443:/websocket"
|
||||||
|
echo "Like: fallback=:1443:/websocket"
|
||||||
|
echo "Like: fallback=:1443"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${fhost}" ]; then
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fport "${fport}" --arg fpath "${fpath}" '. += {"dest":($fport|tonumber), "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "${fpath}" ]; then
|
||||||
|
fdest="${fhost}:${fport}"
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "xver":1}'`
|
||||||
|
else
|
||||||
|
Jfallback=`echo '{}' |jq --arg fdest "${fdest}" --arg fpath "${fpath}" '. += {"dest":$fdest, "path":$fpath, "xver":1}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --argjson jfallback "$Jfallback" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws", "security":"tls" } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{"alpn":["http/1.1"]} } ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"wsSettings":{"path":$wspath}} ' \
|
||||||
|
|sponge $XCONF
|
||||||
|
|
||||||
|
for certroot in "${certpath[@]}"
|
||||||
|
do
|
||||||
|
if [ -f "${certroot}/${domain}/fullchain.cer" ] && [ -f "${certroot}/${domain}/${domain}.key" ]; then
|
||||||
|
fullchain="${certroot}/${domain}/fullchain.cer"
|
||||||
|
prvkey="${certroot}/${domain}/${domain}.key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
||||||
|
echo "TLS cert missing?"
|
||||||
|
echo "Abort."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.tlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
||||||
|
|sponge $XCONF
|
||||||
Reference in New Issue
Block a user