Init import

This commit is contained in:
Samuel Huang
2021-08-16 00:04:22 +10:00
commit c7bd82d7e4
13 changed files with 1487 additions and 0 deletions

32
Dockerfile.amd64 Normal file
View 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
View 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
View 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
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.

89
README.md Normal file
View 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.
![docker-build](https://github.com/samuelhbne/server-xray/workflows/docker-buildx-latest/badge.svg)
## [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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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