Initial REALITY support

This commit is contained in:
Samuel Huang
2024-09-10 20:37:42 +10:00
parent 73f40620a4
commit a8b2ece228
29 changed files with 1673 additions and 1601 deletions

View File

@@ -31,28 +31,33 @@ COPY nginx-proxy.tpl /etc/nginx/conf.d/
COPY nginx-grpc.tpl /etc/nginx/conf.d/
COPY nginx-ws.tpl /etc/nginx/conf.d/
ADD server-lx.sh /server-lx.sh
ADD server-ls.sh /server-ls.sh
ADD server-ms.sh /server-ms.sh
ADD server-ts.sh /server-ts.sh
#ADD server-lgp.sh /server-lgp.sh
ADD server-lgr.sh /server-lgr.sh
ADD server-lgt.sh /server-lgt.sh
ADD server-lsw.sh /server-lsw.sh
ADD server-lsg.sh /server-lsg.sh
ADD server-lss.sh /server-lss.sh
#ADD server-lsp.sh /server-lsp.sh
ADD server-lst.sh /server-lst.sh
ADD server-msw.sh /server-msw.sh
ADD server-tsw.sh /server-tsw.sh
ADD server-ltr.sh /server-ltr.sh
ADD server-ltt.sh /server-ltt.sh
ADD server-lpw.sh /server-lpw.sh
ADD server-lpg.sh /server-lpg.sh
ADD server-lps.sh /server-lps.sh
#ADD server-lwp.sh /server-lwp.sh
ADD server-lwt.sh /server-lwt.sh
ADD server-mpw.sh /server-mpw.sh
ADD server-tpw.sh /server-tpw.sh
ADD server-mtt.sh /server-mtt.sh
#ADD server-mwp.sh /server-mwp.sh
ADD server-mwt.sh /server-mwt.sh
ADD server-nginx.sh /server-nginx.sh
#ADD server-twp.sh /server-twp.sh
ADD server-ttt.sh /server-ttt.sh
ADD server-twt.sh /server-twt.sh
ADD run.sh /run.sh
ADD server-nginx.sh /server-nginx.sh
ADD fallback.sh /fallback.sh
ADD addusertj.sh /addusertj.sh
ADD adduser.sh /adduser.sh
ADD run.sh /run.sh
RUN chmod 755 /*.sh

74
adduser.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
usage() {
echo "Usage: adduser -p <port-num> -u <user> -c <email-comment> -f <flow-type>" >&2
}
TEMP=`getopt -o c:f:p:u: --long comment:flow:port:,user: -n "$0" -- $@`
if [ $? != 0 ] ; then usage; exit 1 ; fi
eval set -- "$TEMP"
while true ; do
case "$1" in
-c|--comment)
comment="$2"
shift 2
;;
-f|flow)
flow="$2"
shift 2
;;
-p|--port)
port="$2"
shift 2
;;
-u|--user)
user="$2"
shift 2
;;
--)
shift
break
;;
*)
echo "Unknown option: $1" >&2
usage;
exit 1
;;
esac
done
if [ -z "${port}" ]; then
echo "Error: port undefined." >&2
usage
exit 1 ;
fi
IFS=':'
uopt=(${user})
uopt=(${uopt[@]})
uid="${uopt[0]}"
level="${uopt[1]}"
email="${uopt[2]}"
if [ -z "${uid}" ]; then
echo "Error: Undefined UID \"$user\"" >&2
echo "Correct user format: user=<uid>[:level:email]" >&2
echo "Like: user=myid:0:me@g.cn" >&2
echo "Like: user=myid::me@g.cn" >&2
echo "Like: user=myid:0" >&2
echo "Like: user=myid" >&2
exit 1
fi
if [ -z "${level}" ]; then
level=0
fi
if [ -z "${email}" ]; then
email="${uid}@${comment}"
fi
jq --arg port "${port}" --arg uid "${uid}" --arg level "${level}" --arg email "${email}" --arg flow "${flow}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"id":$uid, "flow":$flow, "level":($level|tonumber), "email":$email} ] ' \

74
addusertj.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
usage() {
echo "Usage: adduser -p <port-num> -u <user> -c <email-comment> -f <flow-type>" >&2
}
TEMP=`getopt -o c:f:p:u: --long comment:flow:port:,user: -n "$0" -- $@`
if [ $? != 0 ] ; then usage; exit 1 ; fi
eval set -- "$TEMP"
while true ; do
case "$1" in
-c|--comment)
comment="$2"
shift 2
;;
-f|flow)
flow="$2"
shift 2
;;
-p|--port)
port="$2"
shift 2
;;
-u|--user)
user="$2"
shift 2
;;
--)
shift
break
;;
*)
echo "Unknown option: $1" >&2
usage;
exit 1
;;
esac
done
if [ -z "${port}" ]; then
echo "Error: port undefined." >&2
usage
exit 1 ;
fi
IFS=':'
uopt=(${user})
uopt=(${uopt[@]})
psw="${uopt[0]}"
level="${uopt[1]}"
email="${uopt[2]}"
if [ -z "${uid}" ]; then
echo "Error: Undefined UID \"$user\"" >&2
echo "Correct user format: user=<password>[:level:email]" >&2
echo "Like: user=mypw:0:me@g.cn" >&2
echo "Like: user=mypw::me@g.cn" >&2
echo "Like: user=mypw:0" >&2
echo "Like: user=mypw" >&2
exit 1
fi
if [ -z "${level}" ]; then
level=0
fi
if [ -z "${email}" ]; then
email="${uid}@${comment}"
fi
jq --arg port "${port}" --arg psw "${psw}" --arg level "${level}" --arg email "${email}" --arg flow "${flow}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"password":$psw, "flow":$flow, "level":($level|tonumber), "email":$email} ] ' \

79
fallback.sh Executable file
View File

@@ -0,0 +1,79 @@
#!/bin/bash
usage() {
echo "Usage: fallback -p <port-num> -f <fallback-dest>" >&2
}
TEMP=`getopt -o f:p: --long port:,fallback: -n "$0" -- $@`
if [ $? != 0 ] ; then usage; exit 1 ; fi
eval set -- "$TEMP"
while true ; do
case "$1" in
-p|--port)
port="$2"
shift 2
;;
-f|--fallback)
fallback="$2"
shift 2
;;
--)
shift
break
;;
*)
echo "Unknown option: $1" >&2
usage;
exit 1
;;
esac
done
if [ -z "${port}" ]; then
echo "Error: port undefined." >&2
usage
exit 1 ;
fi
if [ -z "${fallback}" ]; then
echo "Error: fallback undefined." >&2
usage
exit 1 ;
fi
IFS=':'
fopt=(${fallback})
fopt=(${fopt[@]})
fhost="${fopt[0]}"
fport="${fopt[1]}"
fpath="${fopt[2]}"
fdest=$fhost:$fport
if [ -z "${fport}" ]; then
echo "Incorrect fallback format: ${fallback}"
echo "Correct fallback: fallback=[host]<:port>[:path]"
echo "Like: fallback=baidu.com:443:/path"
echo "Like: fallback=:1443:/path"
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
jq --arg port "${port}" --argjson jfallback "$Jfallback" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.fallbacks ) += [ $jfallback ] ' \

63
run.sh
View File

@@ -9,37 +9,38 @@ XCONF=/tmp/server-xray.json
usage() {
echo "server-xray <server-options>"
echo " --lx <VLESS-XTLS option> [p=443,]d=domain.com,u=id[:level[:email]]"
echo " --ls <VLESS-TLS option> [p=443,]d=domain.com,u=id[:level[:email]]"
echo " --ms <VMESS-TLS option> [p=443,]d=domain.com,u=id[:level[:email]]"
echo " --ts <TROJAN-TLS option> [p=443,]d=domain.com,u=psw[:level[:email]]"
echo " --lsg <VLESS-TLS-GRPC option> [p=443,]d=domain.com,u=id[:level[:email]],s=svcname"
echo " --lss <VLESS-TLS-SPLT option> [p=443,]d=domain.com,u=id[:level[:email]],w=/webpath"
echo " --lsw <VLESS-TLS-WS option> [p=443,]d=domain.com,u=id[:level[:email]],w=/wspath"
echo " --msw <VMESS-TLS-WS option> [p=443,]d=domain.com,u=id[:level[:email]],w=/wspath"
echo " --tsw <TROJAN-TLS-WS option> [p=443,]d=domain.com,u=psw[:level[:email]],w=/wspath"
echo " --lpg <VLESS-PLN-GRPC option> [p=443,]u=id[:level[:email]],s=svcname"
echo " --lps <VLESS-PLN-SPLT option> [p=443,]u=id[:level[:email]],w=/webpath"
echo " --lpw <VLESS-PLN-WS option> [p=443,]u=id[:level[:email]],w=/wspath"
echo " --mpw <VMESS-PLN-WS option> [p=443,]u=id[:level[:email]],w=/wspath"
echo " --tpw <TROJAN-PLN-WS option> [p=443,]u=psw[:level[:email]],w=/wspath"
echo " --ng-opt <nginx-options> [p=443,]d=domain0.com[,d=domain1.com][...]"
echo " --ng-proxy <nginx-proxy-options> [d=domain0.com,][d=domain1.com,]p=port-backend,l=location,n=ws|grpc|splt"
echo " --domain-block <domain-rule> Add a domain rule for routing block, like geosite:category-ads-all"
echo " --ip-block <ip-rule> Add a ip-addr rule for routing block, like geoip:private"
echo " --cn-block Add routing rules to avoid domains and IPs located in China being proxied"
echo " -u|--user <global-user-options> u=id0[:level[:email]][,u=id1][...]"
echo " -k|--hook <hook-url> DDNS update or notifing URL to be hit"
echo " -r|--request-domain <domain-name> Domain name to request for letsencrypt cert"
echo " -c|--cert-home <cert-home-dir> Reading TLS certs from folder <cert-home-dir>/<domain-name>/"
echo " -i|--stdin Read config from STDIN instead of auto generation"
echo " -j|--json '{"log":{"loglevel":"info"}' Json snippet to merge into the config"
echo " -d|--debug Start in debug mode with verbose output"
echo " --lgp <VLESS-GRPC-PLN option> p=11443,u=id1,u=id2...,s=svcname"
echo " --lgr <VLESS-GRPC-RLTY option> p=12443,u=id1,u=id2...,s=svcname,d=dest.com,pub=xxx,prv=yyy"
echo " --lgt <VLESS-GRPC-TLS option> p=13443,u=id1,u=id2...,s=svcname,d=domain.com"
echo " --lsp <VLESS-SPLT-PLN option> p=14443,u=id1,u=id2...,w=/webpath"
echo " --lst <VLESS-SPLT-TLS option> p=16443,u=id1,u=id2...,w=/webpath,d=domain.com"
echo " --ltr <VLESS-TCP-RLTY option> p=17443,u=id1,u=id2...,[xtls],d=dest.com,pub=xxx,prv=yyy"
echo " --ltt <VLESS-TCP-TLS option> p=18443,u=id1,u=id2...,[xtls],d=domain.com"
echo " --lwp <VLESS-WS-PLN option> p=19443,u=id1,u=id2...,w=/wskpath"
echo " --lwt <VLESS-WS-TLS option> p=22443,u=id1,u=id2...,w=/wskpath,d=domain.com"
echo " --mtt <VMESS-TCP-TLS option> p=23443,u=id1,u=id2...,d=domain.com"
echo " --mwp <VMESS-WS-PLN option> p=24443,u=id1,u=id2...,w=/wskpath"
echo " --mwt <VMESS-WS-TLS option> p=25443,u=id1,u=id2...,w=/wskpath,d=domain.com"
echo " --ttt <TROJAN-TCP-TLS option> p=26443,u=pw1,u=pw2...,d=domain.com"
echo " --twp <TROJAN-WS-PLN option> p=27443,u=pw1,u=pw2...,w=/wskpath"
echo " --twt <TROJAN-WS-TLS option> p=28443,u=pw1,u=pw2...,w=/wskpath,d=domain.com"
echo " --ng-opt <nginx-options> p=443,d=domain0.com,d=domain1.com..."
echo " --ng-proxy <nginx-proxy-options> d=domain0.com,d=domain1.com,p=port-backend,l=location,n=ws|grpc|splt"
echo " --domain-block <domain-rule> Add a domain rule for routing block, like geosite:category-ads-all"
echo " --ip-block <ip-rule> Add a ip-addr rule for routing block, like geoip:private"
echo " --cn-block Add routing rules to avoid domains and IPs located in China being proxied"
echo " -u|--user <global-user-options> u=id0,u=id1..."
echo " -k|--hook <hook-url> DDNS update or notifing URL to be hit"
echo " -r|--request-domain <domain-name> Domain name to request for letsencrypt cert"
echo " -c|--cert-home <cert-home-dir> Reading TLS certs from folder <cert-home-dir>/<domain-name>/"
echo " -i|--stdin Read config from STDIN instead of auto generation"
echo " -j|--json Json snippet to merge into the config. Say '{"log":{"loglevel":"info"}'"
echo " -d|--debug Start in debug mode with verbose output"
}
Jrules='{"rules":[]}'
TEMP=`getopt -o u:k:r:c:j:di --long user:,hook:,request-domain:,cert-home:,ip-block:,domain-block:,cn-block,lx:,ls:,ms:,ts:,lsg:,lss:,lsw:,msw:,tsw:,lpg:,lps:,lpw:,mpw:,tpw:,ng-opt:,ng-proxy:,json:,stdin,debug -n "$0" -- $@`
TEMP=`getopt -o u:k:r:c:j:di --long user:,hook:,request-domain:,cert-home:,ip-block:,domain-block:,cn-block,lgp:,lgr:,lgt:,lsp:,lst:,ltr:,ltt:,lwp:,lwt:,mtt:,mwp:,mwt:,ttt:,twp:,twt:,ng-opt:,ng-proxy:,json:,stdin,debug -n "$0" -- $@`
if [ $? != 0 ] ; then usage; exit 1 ; fi
eval set -- "$TEMP"
@@ -73,9 +74,9 @@ while true ; do
INJECT+=("$2")
shift 2
;;
--lx|--ls|--ms|--ts|--lsg|--lss|--lsw|--msw|--tsw|--lpg|--lps|--lpw|--mpw|--tpw)
--lgp|--lgr|--lgt|--lsp|--lst|--ltr|--ltt|--lwp|--lwt|--mtt|--mwp|--mwt|--ttt|--twp|--twt)
SVC=`echo $1|tr -d '\-\-'`
SVCMD+=("${DIR}server-${SVC}.sh $2")
SVCMD+=("${DIR}/server-${SVC}.sh $2")
shift 2
;;
--domain-block)
@@ -177,8 +178,6 @@ if [ -n "${SVCMD}" ]; then
if [ "${DEBUG}" = "1" ]; then
cat $XCONF |jq '.log.loglevel |="debug"' |sponge $XCONF
echo
cat $XCONF
echo
fi
if [ -n "${NGOPT}" ]; then
@@ -208,6 +207,8 @@ if [ -n "${SVCMD}" ]; then
done
fi
cat $XCONF
echo
exec /usr/local/bin/xray -c $XCONF
else

View File

@@ -1,39 +1,40 @@
#!/bin/bash
usage() {
echo "Usage: server-lpg <x=xray-config-file>,<p=listen-port>,<u=xxx-xxx[:0[:a@mail.com]]>,<s=svcname>"
}
DIR=`dirname $0`
port=443
usage() {
echo "VLESS-GRPC-PLAIN builder"
echo "Usage: server-lgp <x=xray-config-file>,<p=listen-port>,<s=svcname>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
s|service)
service="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
x|xconf)
xconf="${kv[1]}"
;;
esac
done
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1
exit 1 ;
fi
if [ -z "${service}" ]; then
echo "Error: service name undefined."
echo "Error: service undefined."
usage
exit 1
fi
@@ -44,44 +45,34 @@ if [ -z "${xuser}" ]; then
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lgp.$domain $flowopt | sponge $XCONF
done
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"grpc", "security":"none" } ' \
|sponge $XCONF
# Network settings
cat $XCONF |jq --arg port "${port}" --arg service "${service}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"grpcSettings":{"serviceName":$service}} ' \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"grpc","grpcSettings":{"serviceName":$service} } ' \
|sponge $XCONF
# Plain settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|sponge $XCONF

134
server-lgr.sh Executable file
View File

@@ -0,0 +1,134 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VLESS-GRPC-REALITY builder"
echo "Usage: server-lgr <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<s=svcname>,[xtls],<d=dest.com>,[pub=xxx,prv=yyy],<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
c|certhome)
certhome="${kv[1]}"
;;
d|dest)
dest="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
s|service)
service="${kv[1]}"
;;
shortId)
shortIds+=("${kv[1]}")
;;
prv|privateKey)
prvkey="${kv[1]}"
;;
pub|publicKey)
pubkey="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
if [ -z "${dest}" ]; then
echo "Error: dest undefined."
usage
exit 1
fi
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${service}" ]; then
echo "Error: service undefined."
usage
exit 1
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -z "${prvkey}" ] || [ -z "${pubkey}" ] ; then
echo "Warning: PublicKey / PrivateKey undefined, Generated new..."
kv=(`/usr/local/bin/xray x25519|cut -d ' ' -f3|tr ' '`)
prvkey="${kv[0]}"
pubkey="${kv[1]}"
echo "PublicKey: $pubkey"
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lgr.$dest $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg service "${service}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"grpc","grpcSettings":{"serviceName":$service} } ' \
|sponge $XCONF
# Reality settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"reality"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" --arg dest "${dest}" --arg pubkey "${pubkey}" --arg prvkey "${prvkey}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"realitySettings":{"show":true,"dest":"\($dest):443","serverNames":[$dest,""],"privateKey":$prvkey,"publicKey":$pubkey,"shortIds":[""]} } ' \
|sponge $XCONF
cat $XCONF |jq '( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.realitySettings.shortIds ) +=$ARGS.positional' \
--arg port "${port}" --args ${shortIds[@]} \
|sponge $XCONF

View File

@@ -1,7 +1,10 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "Usage: server-lsg <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=xxx-xxx[:0[:a@mail.com]]>,<s=svcname>"
echo "VLESS-GRPC-TLS builder"
echo "Usage: server-lgt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<s=svcname>,[xtls],<d=domain.com>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
@@ -9,24 +12,33 @@ for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
s|service)
service="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
@@ -36,18 +48,24 @@ if [ -z "${certhome}" ]; then
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${service}" ]; then
echo "Error: service undefined."
usage
exit 1
fi
@@ -58,47 +76,11 @@ if [ -z "${xuser}" ]; then
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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
cat $XCONF |jq --arg port "${port}" --arg service "${service}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"grpc", "grpcSettings":{"serviceName":$service}, "security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{"alpn":["http/2"]}} ' \
|sponge $XCONF
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
@@ -111,6 +93,42 @@ if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lgt.$domain $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg service "${service}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"grpc","grpcSettings":{"serviceName":$service} } ' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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

View File

@@ -1,129 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-lps <x=xray-config-file>,<p=listen-port>,<u=myid[:0[:a@mail.com]]>,<w=web-path>"
}
port=443
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
webpath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
esac
done
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${webpath}" ]; then
echo "Error: webpath undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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":"splithttp", "security":"none" } ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" --arg webpath "${webpath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"splithttpSettings":{"path":$webpath}} ' \
|sponge $XCONF

View File

@@ -1,129 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-lpw <x=xray-config-file>,<p=listen-port>,<u=myid[:0[:a@mail.com]]>,<w=websocket-path>"
}
port=443
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
wspath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
esac
done
if [ -z "${xconf}" ]; then
echo "Error: xconf 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
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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":"none" } ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"wsSettings":{"path":$wspath}} ' \
|sponge $XCONF

View File

@@ -1,155 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-ls <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=xxx-xxx[:0[:a@mail.com]]>"
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${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 "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
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 ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
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

78
server-lsp.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VLESS-SPLT-PLAIN builder"
echo "Usage: server-lsp <x=xray-config-file>,<p=listen-port>,<w=webpath>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
webpath="${kv[1]}"
;;
x|xconf)
xconf="${kv[1]}"
;;
esac
done
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${webpath}" ]; then
echo "Error: webpath undefined."
usage
exit 1
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lsp.$domain $flowopt | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"splithttp","splithttpSettings":{"path":$webpath}} ' \
|sponge $XCONF
# Plain settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|sponge $XCONF

View File

@@ -1,168 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-lss <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=xxx-xxx[:0[:a@mail.com]]>,<w=web-path>"
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
webpath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
esac
done
if [ -z "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
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 "${webpath}" ]; then
echo "Error: webpath undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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":"splithttp", "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 webpath "${webpath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"splithttpSettings":{"path":$webpath}} ' \
|sponge $XCONF
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
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

134
server-lst.sh Executable file
View File

@@ -0,0 +1,134 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VLESS-SPLT-TLS builder"
echo "Usage: server-lst <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<w=webpath>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
c|certhome)
certhome="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
webpath="${kv[1]}"
;;
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
if [ -z "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${webpath}" ]; then
echo "Error: webpath undefined."
usage
exit 1
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
echo "TLS cert missing?"
echo "Abort."
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lst.$domain $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"splithttp","splithttpSettings":{"path":$webpath}} ' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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

125
server-ltr.sh Executable file
View File

@@ -0,0 +1,125 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VLESS-TCP-REALITY builder"
echo "Usage: server-ltr <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],<d=dest.com>,[pub=xxx,prv=yyy],<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
c|certhome)
certhome="${kv[1]}"
;;
d|dest)
dest="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
shortId)
shortIds+=("${kv[1]}")
;;
prv|privateKey)
prvkey="${kv[1]}"
;;
pub|publicKey)
pubkey="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
if [ -z "${dest}" ]; then
echo "Error: dest undefined."
usage
exit 1
fi
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -z "${prvkey}" ] || [ -z "${pubkey}" ] ; then
echo "Warning: PublicKey / PrivateKey undefined, Generated new..."
kv=(`/usr/local/bin/xray x25519|cut -d ' ' -f3|tr ' '`)
prvkey="${kv[0]}"
pubkey="${kv[1]}"
echo "PublicKey: $pubkey"
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c ltr.$dest $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \
|sponge $XCONF
# Reality settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"reality"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" --arg dest "${dest}" --arg pubkey "${pubkey}" --arg prvkey "${prvkey}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"realitySettings":{"show":true,"dest":"\($dest):443","serverNames":[$dest,""],"privateKey":$prvkey,"publicKey":$pubkey,"shortIds":[""]} } ' \
|sponge $XCONF
cat $XCONF |jq '( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.realitySettings.shortIds ) +=$ARGS.positional' \
--arg port "${port}" --args ${shortIds[@]} \
|sponge $XCONF

125
server-ltt.sh Executable file
View File

@@ -0,0 +1,125 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VLESS-TCP-TLS builder"
echo "Usage: server-ltt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],<d=domain.com>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
c|certhome)
certhome="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
if [ -z "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
echo "TLS cert missing?"
echo "Abort."
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c ltt.$dest $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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

78
server-lwp.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VLESS-WS-PLAIN builder"
echo "Usage: server-lwp <x=xray-config-file>,<p=listen-port>,<w=wskpath>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
webpath="${kv[1]}"
;;
x|xconf)
xconf="${kv[1]}"
;;
esac
done
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
usage
exit 1
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lwp.$domain $flowopt | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}}' \
|sponge $XCONF
# Plain settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|sponge $XCONF

View File

@@ -1,7 +1,10 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "Usage: server-lsw <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=xxx-xxx[:0[:a@mail.com]]>,<w=websocket-path>"
echo "VLESS-WS-TLS builder"
echo "Usage: server-lwt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<w=wskpath>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
@@ -9,26 +12,32 @@ for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
wspath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
@@ -39,18 +48,24 @@ if [ -z "${certhome}" ]; then
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
usage
exit 1
fi
@@ -61,97 +76,12 @@ if [ -z "${xuser}" ]; then
exit 1
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
@@ -163,6 +93,42 @@ if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lwt.$domain $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}}' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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

View File

@@ -1,129 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-mpw <x=xray-config-file>,<p=listen-port>,<u=myid[:0[:a@mail.com]]>,<w=websocket-path>"
}
port=443
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
wspath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
esac
done
if [ -z "${xconf}" ]; then
echo "Error: xconf 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
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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":"none" } ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"wsSettings":{"path":$wspath}} ' \
|sponge $XCONF

View File

@@ -1,155 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-ms <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=xxx-xxx[:0[:a@mail.com]]>"
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${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 "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
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 ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
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

125
server-mtt.sh Executable file
View File

@@ -0,0 +1,125 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VMESS-TCP-TLS builder"
echo "Usage: server-mtt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
c|certhome)
certhome="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
if [ -z "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
echo "TLS cert missing?"
echo "Abort."
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vmess", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c mtt.$dest $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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

78
server-mwp.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "VMESS-WS-PLAIN builder"
echo "Usage: server-mwp <x=xray-config-file>,<p=listen-port>,<w=wskpath>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
webpath="${kv[1]}"
;;
x|xconf)
xconf="${kv[1]}"
;;
esac
done
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
usage
exit 1
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vmess", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c mwp.$domain $flowopt | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}}' \
|sponge $XCONF
# Plain settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|sponge $XCONF

View File

@@ -1,7 +1,10 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "Usage: server-msw <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=xxx-xxx[:0[:a@mail.com]]>,<w=websocket-path>"
echo "VMESS-WS-TLS builder"
echo "Usage: server-mwt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<w=wskpath>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
@@ -9,26 +12,32 @@ for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
wspath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
@@ -39,18 +48,24 @@ if [ -z "${certhome}" ]; then
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
usage
exit 1
fi
@@ -61,97 +76,12 @@ if [ -z "${xuser}" ]; then
exit 1
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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=<uid>[:level:email]"
echo "Like: user=myid:0:me@g.cn"
echo "Like: user=myid::me@g.cn"
echo "Like: user=myid:0"
echo "Like: user=myid"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
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
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
@@ -163,6 +93,42 @@ if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vmess", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c mwt.$domain $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}} ' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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

View File

@@ -1,129 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-tpw <x=xray-config-file>,<p=listen-port>,<u=password[:level[:email]],<w=websocket-path>"
}
port=443
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
wspath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
esac
done
if [ -z "${xconf}" ]; then
echo "Error: xconf 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
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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[:level[:email]"
echo "Like: user=mypass:0:me@g.cn"
echo "Like: user=mypass::me@g.cn"
echo "Like: user=mypass:0"
echo "Like: user=mypass"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
fi
cat $XCONF |jq --arg port "${port}" --arg pass "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"password":$pass, "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":"none" } ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"wsSettings":{"path":$wspath}} ' \
|sponge $XCONF

View File

@@ -1,155 +0,0 @@
#!/bin/bash
usage() {
echo "Usage: server-ts <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=password[:level[:email]]>"
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${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 "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
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 ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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[:level[:email]"
echo "Like: user=mypass:0:me@g.cn"
echo "Like: user=mypass::me@g.cn"
echo "Like: user=mypass:0"
echo "Like: user=mypass"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
fi
cat $XCONF |jq --arg port "${port}" --arg pass "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"password":$pass, "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
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
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

126
server-ttt.sh Executable file
View File

@@ -0,0 +1,126 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "TROJAN-TCP-TLS builder"
echo "Usage: server-ttt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<u=pw0>,<u=pw1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
case "${kv[0]}" in
c|certhome)
certhome="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
if [ -z "${certhome}" ]; then
echo "Error: certhome undefined."
usage
exit 1
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
fi
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
echo "TLS cert missing?"
echo "Abort."
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"trojan", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/addusertj.sh -p $port -u ${xu} -c ttt.$dest $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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

78
server-twp.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "TROJAN-WS-PLAIN builder"
echo "Usage: server-twp <x=xray-config-file>,<p=listen-port>,<w=wskpath>,<u=pw0>,<u=pw1>..."
}
options=(`echo $1 |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
wspath="${kv[1]}"
;;
x|xconf)
xconf="${kv[1]}"
;;
esac
done
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
usage
exit 1
fi
if [ -z "${xuser}" ]; then
echo "Error: user undefined."
usage
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"trojan", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/addusertj.sh -p $port -u ${xu} -c twp.$domain $flowopt | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}} ' \
|sponge $XCONF
# Plain settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|sponge $XCONF

View File

@@ -1,7 +1,10 @@
#!/bin/bash
DIR=`dirname $0`
usage() {
echo "Usage: server-tsw <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=mydomain.com>,<u=password[:level[:email]],<w=websocket-path>"
echo "TROJAN-WS-TLS builder"
echo "Usage: server-twt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<w=wskpath>,<u=pw0>,<u=pw1>..."
}
options=(`echo $1 |tr ',' ' '`)
@@ -9,26 +12,32 @@ for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
x|xconf)
xconf="${kv[1]}"
;;
c|certhome)
certhome="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
d|domain)
domain="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
;;
flow)
flow="${kv[1]}"
;;
p|port)
port="${kv[1]}"
;;
u|user)
xuser+=("${kv[1]}")
;;
w|wpath)
wspath="${kv[1]}"
;;
f|fallback)
fallback+=("${kv[1]}")
x|xconf)
xconf="${kv[1]}"
;;
xtls)
flow="xtls-rprx-vision"
;;
esac
done
@@ -39,18 +48,24 @@ if [ -z "${certhome}" ]; then
exit 1
fi
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
usage
exit 1
fi
if [ -z "${port}" ]; then
port=443
if [ -n "${flow}" ]; then
flowopt="-f ${flow}"
fi
if [ -z "${domain}" ]; then
echo "Error: domain undefined."
if [ -z "${port}" ]; then
echo "Error: port undefined."
usage
exit 1 ;
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
usage
exit 1
fi
@@ -61,97 +76,12 @@ if [ -z "${xuser}" ]; then
exit 1
fi
if [ -z "${wspath}" ]; then
echo "Error: wspath undefined."
if [ -z "${xconf}" ]; then
echo "Error: xconf undefined."
usage
exit 1
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $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[:level[:email]"
echo "Like: user=mypass:0:me@g.cn"
echo "Like: user=mypass::me@g.cn"
echo "Like: user=mypass:0"
echo "Like: user=mypass"
exit 1
fi
if [ -z "${uopt[1]}" ]; then
uopt[1]=0
fi
cat $XCONF |jq --arg port "${port}" --arg pass "${uopt[0]}" --arg level "${uopt[1]}" --arg email "${uopt[2]}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .settings.clients ) += [ {"password":$pass, "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":["h2,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
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
fullchain="${certhome}/${domain}/fullchain.cer"
prvkey="${certhome}/${domain}/${domain}.key"
@@ -163,6 +93,42 @@ if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
exit 2
fi
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
XCONF=$xconf
# Remove existing port number if existing.
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
# Add inbound element
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"trojan", "settings":{"clients":[]}}]' |sponge $XCONF
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
# User settings
for xu in "${xuser[@]}"
do
cat $XCONF | ${DIR}/addusertj.sh -p $port -u ${xu} -c twt.$domain $flowopt | sponge $XCONF
done
# Fallback settings
for fb in "${fallback[@]}"
do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# Network settings
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}} ' \
|sponge $XCONF
# TLS settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|sponge $XCONF
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|sponge $XCONF
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