mirror of
https://github.com/samuelhbne/server-xray.git
synced 2025-12-18 04:44:38 +03:00
Rewrite with json stdout
This commit is contained in:
@@ -56,9 +56,6 @@ ADD server-ttt.sh /server-ttt.sh
|
|||||||
ADD server-twt.sh /server-twt.sh
|
ADD server-twt.sh /server-twt.sh
|
||||||
|
|
||||||
ADD server-nginx.sh /server-nginx.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
|
ADD run.sh /run.sh
|
||||||
|
|
||||||
|
|||||||
85
run.sh
85
run.sh
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
DIR="$(cd $DIR; pwd)"
|
DIR="$(cd $DIR; pwd)"
|
||||||
CERTHOME="/root/.acme.sh"
|
CERTHOME="/opt/cert"
|
||||||
XCONF=/tmp/server-xray.json
|
XCONF=/tmp/server-xray.json
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
@@ -36,7 +36,7 @@ usage() {
|
|||||||
echo " -r|--request-domain <domain-name> Domain name to request for letsencrypt cert"
|
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 " -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 " -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 " -j|--json Json snippet to merge into the config. Say '{"log":{"loglevel":"info"}}'"
|
||||||
echo " -d|--debug Start in debug mode with verbose output"
|
echo " -d|--debug Start in debug mode with verbose output"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,8 @@ while true ; do
|
|||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
-i|--stdin)
|
-i|--stdin)
|
||||||
STDINCONF=1
|
# Read Xray config from STDIN. Run Xray only.
|
||||||
|
exec /usr/local/bin/xray
|
||||||
shift 1
|
shift 1
|
||||||
;;
|
;;
|
||||||
-d|--debug)
|
-d|--debug)
|
||||||
@@ -77,33 +78,34 @@ while true ; do
|
|||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--lgp|--lgr|--lgt|--lsp|--lst|--ltr|--ltt|--lwp|--lwt|--mtt|--mwp|--mwt|--ttt|--twp|--twt)
|
--lgp|--lgr|--lgt|--lsp|--lst|--ltr|--ltt|--lwp|--lwt|--mtt|--mwp|--mwt|--ttt|--twp|--twt)
|
||||||
|
# Alias options
|
||||||
SVC=`echo $1|tr -d '\-\-'`
|
SVC=`echo $1|tr -d '\-\-'`
|
||||||
SVCMD+=("${DIR}/server-${SVC}.sh $2")
|
SVCMD+=("${DIR}/server-${SVC}.sh $2")
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
# Alias options
|
|
||||||
--ltrx|--lttx)
|
--ltrx|--lttx)
|
||||||
|
# Alias options
|
||||||
SVC=`echo $1|tr -d '\-\-'|tr -d x`
|
SVC=`echo $1|tr -d '\-\-'|tr -d x`
|
||||||
SVCMD+=("${DIR}/server-${SVC}.sh $2,xtls")
|
SVCMD+=("${DIR}/server-${SVC}.sh $2,xtls")
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--domain-block)
|
--domain-block)
|
||||||
Jrules=`echo "${Jrules}" | jq --arg blkdomain "$2" \
|
Jrules=`echo "${Jrules}" | jq --arg blkdomain "$2" \
|
||||||
'.rules += [{"type":"field", "outboundTag":"blocked", "domain":[$blkdomain]}]'`
|
'.rules += [{"type":"field","outboundTag":"blocked","domain":[$blkdomain]}]'`
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--ip-block)
|
--ip-block)
|
||||||
Jrules=`echo "${Jrules}" | jq --arg blkip "$2" \
|
Jrules=`echo "${Jrules}" | jq --arg blkip "$2" \
|
||||||
'.rules += [{"type":"field", "outboundTag":"blocked", "ip":[$blkip]}]'`
|
'.rules += [{"type":"field","outboundTag":"blocked","ip":[$blkip]}]'`
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--cn-block)
|
--cn-block)
|
||||||
Jrules=`echo "${Jrules}" | jq --arg igndomain "geosite:geolocation-cn" \
|
Jrules=`echo "${Jrules}" | jq --arg igndomain "geosite:geolocation-cn" \
|
||||||
'.rules += [{"type":"field", "outboundTag":"blocked", "domain":[$igndomain]}]'`
|
'.rules += [{"type":"field","outboundTag":"blocked","domain":[$igndomain]}]'`
|
||||||
Jrules=`echo "${Jrules}" | jq --arg igndomain "geosite:cn" \
|
Jrules=`echo "${Jrules}" | jq --arg igndomain "geosite:cn" \
|
||||||
'.rules += [{"type":"field", "outboundTag":"blocked", "domain":[$igndomain]}]'`
|
'.rules += [{"type":"field","outboundTag":"blocked","domain":[$igndomain]}]'`
|
||||||
Jrules=`echo "${Jrules}" | jq --arg ignip "geoip:cn" \
|
Jrules=`echo "${Jrules}" | jq --arg ignip "geoip:cn" \
|
||||||
'.rules += [{"type":"field", "outboundTag":"blocked", "ip":[$ignip]}]'`
|
'.rules += [{"type":"field","outboundTag":"blocked","ip":[$ignip]}]'`
|
||||||
shift 1
|
shift 1
|
||||||
;;
|
;;
|
||||||
--ng-server)
|
--ng-server)
|
||||||
@@ -165,29 +167,12 @@ if [ -n "${CERTDOMAIN}" ]; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo '{"log":{"loglevel":"warning"},"inbounds":[],"outbounds":[{"tag":"direct","protocol":"freedom"},{"tag":"blocked","protocol":"blackhole"}]}' |jq .|sponge $XCONF
|
xopt="certhome=$CERTHOME"
|
||||||
|
for uopt in "${UOPT[@]}"; do xopt="$xopt,$uopt"; done
|
||||||
xopt="xconf=$XCONF"
|
|
||||||
xopt="$xopt,certhome=$CERTHOME"
|
|
||||||
for uopt in "${UOPT[@]}"
|
|
||||||
do
|
|
||||||
xopt="$xopt,$uopt"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Add routing config
|
|
||||||
Jrouting='{"routing": {"domainStrategy":"AsIs"}}'
|
|
||||||
Jrouting=`echo "${Jrouting}" |jq --argjson jrules "${Jrules}" '.routing += $jrules'`
|
|
||||||
cat $XCONF| jq --argjson jrouting "${Jrouting}" '. += $jrouting' | sponge $XCONF
|
|
||||||
|
|
||||||
# Run Xray only. Read Xray config from STDIN
|
|
||||||
if [ "${STDINCONF}" = "1" ]; then
|
|
||||||
exec /usr/local/bin/xray
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${SVCMD}" ]; then
|
if [ -z "${SVCMD}" ]; then
|
||||||
echo "No Xray service creation found. Quit."
|
echo -e "No Xray service creation found. Quit.\n"
|
||||||
usage;
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start Nginx if necessary
|
# Start Nginx if necessary
|
||||||
@@ -214,46 +199,48 @@ if [ -n "${NGOPT}" ]; then
|
|||||||
ngcmd="${DIR}/server-nginx.sh $NGOPT"
|
ngcmd="${DIR}/server-nginx.sh $NGOPT"
|
||||||
$ngcmd
|
$ngcmd
|
||||||
ret=$?; if [ $ret != 0 ]; then
|
ret=$?; if [ $ret != 0 ]; then
|
||||||
echo ""
|
echo -e "\nNginx config generation failed from the following cmd:\n$ngcmd";
|
||||||
echo "Nginx config generation failed from the following cmd:\n$ngcmd";
|
echo -e "Please check log for details.\n"
|
||||||
echo "Please check log for details"
|
|
||||||
exit $ret;
|
exit $ret;
|
||||||
fi
|
fi
|
||||||
killall nginx
|
killall nginx
|
||||||
nginx;
|
nginx;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Add root config
|
||||||
|
Jroot='{"outbounds":[{"tag":"direct","protocol":"freedom"},{"tag":"blocked","protocol":"blackhole"}]}'
|
||||||
|
|
||||||
|
# Add routing config
|
||||||
|
Jrouting='{"routing":{"domainStrategy":"AsIs"}}'
|
||||||
|
Jrouting=`echo $Jrouting |jq --argjson jrules "${Jrules}" '.routing += $jrules'`
|
||||||
|
|
||||||
|
Jroot=`echo $Jroot| jq --argjson jrouting "${Jrouting}" '. += $jrouting'`
|
||||||
|
|
||||||
# Xray service config generation
|
# Xray service config generation
|
||||||
for svcmd in "${SVCMD[@]}"
|
for svcmd in "${SVCMD[@]}"
|
||||||
do
|
do
|
||||||
svcmd="$svcmd,$xopt"
|
Jsvc=`$svcmd,$xopt`
|
||||||
$svcmd
|
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
echo
|
echo "Service creation command failed: $svcmd,$xopt"
|
||||||
echo "Service creation command failed: $svcmd"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
Jroot=`echo $Jroot| jq --argjson Jsvc "${Jsvc}" '.inbounds += [$Jsvc]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "${DEBUG}" = "1" ]; then
|
if [ -n "${DEBUG}" ]; then loglevel="debug"; else loglevel="warning"; fi
|
||||||
cat $XCONF |jq '.log.loglevel |="debug"' |sponge $XCONF
|
Jroot=`echo $Jroot| jq --arg loglevel "${loglevel}" '.log.loglevel |= $loglevel'`
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${INJECT}" ]; then
|
if [ -n "${INJECT}" ]; then
|
||||||
for JSON_IN in "${INJECT[@]}"
|
for JSON_IN in "${INJECT[@]}"
|
||||||
do
|
do
|
||||||
echo "${JSON_IN}"|jq -ec >/tmp/merge.json
|
Jmerge=`jq -nc "${JSON_IN}"`
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then echo "Invalid json ${JSON_IN}"; exit 1; fi
|
||||||
echo "Invalid json ${JSON_IN}"
|
Jroot=`jq -n --argjson Jroot "${Jroot}" --argjson Jmerge "${Jmerge}" '$Jroot + $Jmerge'`
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
jq -s '.[0] * .[1]' $XCONF /tmp/merge.json |sponge $XCONF
|
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat $XCONF
|
jq -n "$Jroot"
|
||||||
echo
|
jq -n "$Jroot">$XCONF
|
||||||
exec /usr/local/bin/xray -c $XCONF
|
exec /usr/local/bin/xray -c $XCONF
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
104
server-lgp.sh
104
server-lgp.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-GRPC-PLAIN server builder"
|
>&2 echo "VLESS-GRPC-PLAIN server builder"
|
||||||
echo "Usage: server-lgp <x=xray-config-file>,<p=listen-port>,<s=svcname>,<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-lgp <s=svcname>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -15,67 +17,85 @@ do
|
|||||||
d|domain)
|
d|domain)
|
||||||
domain="${kv[1]}"
|
domain="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
s|service)
|
proxy_acpt)
|
||||||
service="${kv[1]}"
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
|
s|serviceName)
|
||||||
|
serviceName="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${service}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: service undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1
|
fi
|
||||||
|
|
||||||
|
if [ -z "${serviceName}" ]; then
|
||||||
|
>&2 echo -e "Error: serviceName undefined.\n"
|
||||||
|
usage; exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
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
|
# inbound frame
|
||||||
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lgp.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@lgp.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
# StreamSettings
|
||||||
cat $XCONF |jq --arg port "${port}" --arg service "${service}" \
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"grpc","grpcSettings":{"serviceName":$service} } ' \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|sponge $XCONF
|
fi
|
||||||
|
|
||||||
# Plain settings
|
# Network settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c --arg serviceName "${serviceName}" '.settings.streamSettings += {"network":"grpc","grpcSettings":{"serviceName":$serviceName}}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|
|
||||||
|sponge $XCONF
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"none"}'`
|
||||||
|
|
||||||
|
# Fallback settings
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $inbound
|
||||||
|
exit 0
|
||||||
|
|||||||
143
server-lgr.sh
143
server-lgr.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-GRPC-REALITY server builder"
|
>&2 echo "VLESS-GRPC-REALITY server builder"
|
||||||
echo "Usage: server-lgr <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<s=svcname>,[xtls],<d=dest.com>,[pub=xx,prv=yy,shortId=zz],<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-lgr ,<s=svcname>,<d=dest.com>,<prv=yy>,[pub=xx],[shortId=zz],<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -12,9 +14,6 @@ for option in "${options[@]}"
|
|||||||
do
|
do
|
||||||
kv=(`echo $option |tr '=' ' '`)
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
case "${kv[0]}" in
|
case "${kv[0]}" in
|
||||||
c|certhome)
|
|
||||||
certhome="${kv[1]}"
|
|
||||||
;;
|
|
||||||
d|dest)
|
d|dest)
|
||||||
dest="${kv[1]}"
|
dest="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
@@ -27,10 +26,16 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
s|service)
|
proxy_acpt)
|
||||||
service="${kv[1]}"
|
acceptProxyProtocol=true
|
||||||
;;
|
;;
|
||||||
shortId)
|
svnm|serverName)
|
||||||
|
serverNames+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
s|serviceName)
|
||||||
|
serviceName="${kv[1]}"
|
||||||
|
;;
|
||||||
|
sid|shortId)
|
||||||
shortIds+=("${kv[1]}")
|
shortIds+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
prv|privateKey)
|
prv|privateKey)
|
||||||
@@ -42,9 +47,6 @@ do
|
|||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -52,83 +54,88 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${dest}" ]; then
|
if [ -z "${dest}" ]; then
|
||||||
echo "Error: dest undefined."
|
>&2 echo -e "Error: Fake Destination undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
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
|
fi
|
||||||
|
|
||||||
if [ -z "${prvkey}" ]; then
|
if [ -z "${prvkey}" ]; then
|
||||||
echo "Warning: PrivateKey undefined, Generated new..."
|
>&2 echo "Warning: PrivateKey undefined, Generated new..."
|
||||||
kv=(`/usr/local/bin/xray x25519|cut -d ' ' -f3|tr ' '`)
|
kv=(`/usr/local/bin/xray x25519|cut -d ' ' -f3|tr ' '`)
|
||||||
prvkey="${kv[0]}"
|
prvkey="${kv[0]}"
|
||||||
pubkey="${kv[1]}"
|
pubkey="${kv[1]}"
|
||||||
echo "PublicKey: $pubkey"
|
>&2 echo "PublicKey: $pubkey"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
|
if [ -z "${serviceName}" ]; then
|
||||||
|
>&2 echo -e "Error: serviceName undefined.\n"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
XCONF=$xconf
|
if [ -z "${xuser}" ]; then
|
||||||
# Remove existing port number if existing.
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Add inbound element
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
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
|
# inbound frame
|
||||||
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
|
|
||||||
# User settings
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lgr.$dest $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@lgr.$dest"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg serviceName "${serviceName}" '.settings.streamSettings += {"network":"grpc","grpcSettings":{"serviceName":$serviceName}}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"reality"}'`
|
||||||
|
|
||||||
|
# Reality settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg dest "${dest}" --arg pubkey "${pubkey}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.realitySettings += {"show":true,"dest":"\($dest):443","serverNames":[$dest],"privateKey":$prvkey,"publicKey":$pubkey}'`
|
||||||
|
|
||||||
|
# serverNames settings
|
||||||
|
if [ -n "${serverNames}" ]; then
|
||||||
|
JserverNames=`printf '%s\n' "${serverNames[@]}"|jq -R|jq -sc`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson JserverNames "${JserverNames}" '.settings.streamSettings.realitySettings.serverNames += $JserverNames'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shortIds settings
|
||||||
|
JshortIds=`printf '%s\n' "${shortIds[@]}"|jq -R|jq -sc`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson JshortIds "${JshortIds}" '.settings.streamSettings.realitySettings.shortIds += $JshortIds'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" --arg service "${service}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
130
server-lgt.sh
130
server-lgt.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-GRPC-TLS server builder"
|
>&2 echo "VLESS-GRPC-TLS server 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>..."
|
>&2 echo "Usage: server-lgt <s=svcname>,<c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -27,15 +29,15 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
s|service)
|
proxy_acpt)
|
||||||
service="${kv[1]}"
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
|
s|serviceName)
|
||||||
|
serviceName="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -43,92 +45,78 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo -e "Error: Certhome undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${service}" ]; then
|
if [ -z "${serviceName}" ]; then
|
||||||
echo "Error: service undefined."
|
>&2 echo -e "Error: serviceName undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
fullchain="${certhome}/${domain}/fullchain.cer"
|
|
||||||
prvkey="${certhome}/${domain}/${domain}.key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
# inbound frame
|
||||||
echo "TLS cert missing?"
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lgt.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@lgt.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg serviceName "${serviceName}" '.settings.streamSettings += {"network":"grpc","grpcSettings":{"serviceName":$serviceName}}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" --arg service "${service}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-SPLT-PLAIN server builder"
|
>&2 echo "VLESS-SPLT-PLAIN server builder"
|
||||||
echo "Usage: server-lsp <x=xray-config-file>,<p=listen-port>,<w=webpath>,<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-lsp <w=webpath>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -15,67 +17,85 @@ do
|
|||||||
d|domain)
|
d|domain)
|
||||||
domain="${kv[1]}"
|
domain="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
w|wpath)
|
w|wpath)
|
||||||
webpath="${kv[1]}"
|
webpath="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${webpath}" ]; then
|
if [ -z "${webpath}" ]; then
|
||||||
echo "Error: webpath undefined."
|
>&2 echo -e "Error: webpath undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
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
|
# inbound frame
|
||||||
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lsp.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@lsp.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
# StreamSettings
|
||||||
cat $XCONF |jq --arg port "${port}" --arg webpath "${webpath}" \
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"splithttp","splithttpSettings":{"path":$webpath}} ' \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|sponge $XCONF
|
fi
|
||||||
|
|
||||||
# Plain settings
|
# Network settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c --arg webpath "${webpath}" '.settings.streamSettings += {"network":"splithttp","splithttpSettings":{"path":$webpath}}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|
|
||||||
|sponge $XCONF
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"none"}'`
|
||||||
|
|
||||||
|
# Fallback settings
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $inbound
|
||||||
|
exit 0
|
||||||
|
|||||||
124
server-lst.sh
124
server-lst.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-SPLT-TLS server builder"
|
>&2 echo "VLESS-SPLT-TLS server 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>..."
|
>&2 echo "Usage: server-lst <w=webpath>,<c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -27,15 +29,15 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
w|wpath)
|
w|wpath)
|
||||||
webpath="${kv[1]}"
|
webpath="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -43,92 +45,78 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo -e "Error: Certhome undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${webpath}" ]; then
|
if [ -z "${webpath}" ]; then
|
||||||
echo "Error: webpath undefined."
|
>&2 echo -e "Error: webpath undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
fullchain="${certhome}/${domain}/fullchain.cer"
|
|
||||||
prvkey="${certhome}/${domain}/${domain}.key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
# inbound frame
|
||||||
echo "TLS cert missing?"
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lst.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@lst.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg webpath "${webpath}" '.settings.streamSettings += {"network":"splithttp","splithttpSettings":{"path":$webpath}}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" --arg webpath "${webpath}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
124
server-ltr.sh
124
server-ltr.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-TCP-REALITY server builder"
|
>&2 echo "VLESS-TCP-REALITY server builder"
|
||||||
echo "Usage: server-ltr <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],[proxy_acpt],<d=dest.com>,[pub=xx,prv=yy,shortId=zz],<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-ltr <d=dest.com>,<prv=yy>,[pub=xx],[shortId=zz],<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -12,9 +14,6 @@ for option in "${options[@]}"
|
|||||||
do
|
do
|
||||||
kv=(`echo $option |tr '=' ' '`)
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
case "${kv[0]}" in
|
case "${kv[0]}" in
|
||||||
c|certhome)
|
|
||||||
certhome="${kv[1]}"
|
|
||||||
;;
|
|
||||||
d|dest)
|
d|dest)
|
||||||
dest="${kv[1]}"
|
dest="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
@@ -30,7 +29,10 @@ do
|
|||||||
proxy_acpt)
|
proxy_acpt)
|
||||||
acceptProxyProtocol=true
|
acceptProxyProtocol=true
|
||||||
;;
|
;;
|
||||||
shortId)
|
svnm|serverName)
|
||||||
|
serverNames+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
sid|shortId)
|
||||||
shortIds+=("${kv[1]}")
|
shortIds+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
prv|privateKey)
|
prv|privateKey)
|
||||||
@@ -42,9 +44,6 @@ do
|
|||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -52,84 +51,83 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${dest}" ]; then
|
if [ -z "${dest}" ]; then
|
||||||
echo "Error: dest undefined."
|
>&2 echo -e "Error: Fake Destination undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
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
|
fi
|
||||||
|
|
||||||
if [ -z "${prvkey}" ]; then
|
if [ -z "${prvkey}" ]; then
|
||||||
echo "Warning: PrivateKey undefined, Generated new..."
|
>&2 echo "Warning: PrivateKey undefined, Generated new..."
|
||||||
kv=(`/usr/local/bin/xray x25519|cut -d ' ' -f3|tr ' '`)
|
kv=(`/usr/local/bin/xray x25519|cut -d ' ' -f3|tr ' '`)
|
||||||
prvkey="${kv[0]}"
|
prvkey="${kv[0]}"
|
||||||
pubkey="${kv[1]}"
|
pubkey="${kv[1]}"
|
||||||
echo "PublicKey: $pubkey"
|
>&2 echo "PublicKey: $pubkey"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
|
if [ -z "${xuser}" ]; then
|
||||||
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
XCONF=$xconf
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
# Remove existing port number if existing.
|
|
||||||
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
|
|
||||||
|
|
||||||
# Add inbound element
|
# inbound frame
|
||||||
cat $XCONF |jq --arg port "${port}" '.inbounds +=[{"port":($port|tonumber), "protocol":"vless", "settings":{"clients":[]}}]' |sponge $XCONF
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
|
|
||||||
|
|
||||||
# User settings
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c ltr.$dest $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
done
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
# Fallback settings
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
for fb in "${fallback[@]}"
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
do
|
if [ -z "${email}" ]; then email="${uid}@ltr.$dest"; fi
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# StreamSettings
|
# StreamSettings
|
||||||
if [ -n "${acceptProxyProtocol}" ]; then
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"sockopt":{"acceptProxyProtocol":true}} ' \
|
|
||||||
|sponge $XCONF
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Network settings
|
# Network settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"network":"tcp"}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \
|
|
||||||
|sponge $XCONF
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"reality"}'`
|
||||||
|
|
||||||
# Reality settings
|
# Reality settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c --arg dest "${dest}" --arg pubkey "${pubkey}" --arg prvkey "${prvkey}" \
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"reality"} ' \
|
'.settings.streamSettings.realitySettings += {"show":true,"dest":"\($dest):443","serverNames":[$dest],"privateKey":$prvkey,"publicKey":$pubkey}'`
|
||||||
|sponge $XCONF
|
|
||||||
|
|
||||||
cat $XCONF |jq --arg port "${port}" --arg dest "${dest}" --arg pubkey "${pubkey}" --arg prvkey "${prvkey}" \
|
# serverNames settings
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"realitySettings":{"show":true,"dest":"\($dest):443","serverNames":[$dest,""],"privateKey":$prvkey,"publicKey":$pubkey,"shortIds":[""]} } ' \
|
if [ -n "${serverNames}" ]; then
|
||||||
|sponge $XCONF
|
JserverNames=`printf '%s\n' "${serverNames[@]}"|jq -R|jq -sc`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson JserverNames "${JserverNames}" '.settings.streamSettings.realitySettings.serverNames += $JserverNames'`
|
||||||
|
fi
|
||||||
|
|
||||||
cat $XCONF |jq '( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.realitySettings.shortIds ) +=$ARGS.positional' \
|
# shortIds settings
|
||||||
--arg port "${port}" --args ${shortIds[@]} \
|
JshortIds=`printf '%s\n' "${shortIds[@]}"|jq -R|jq -sc`
|
||||||
|sponge $XCONF
|
inbound=`echo $inbound| jq -c --argjson JshortIds "${JshortIds}" '.settings.streamSettings.realitySettings.shortIds += $JshortIds'`
|
||||||
|
|
||||||
|
# Fallback settings
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $inbound
|
||||||
|
exit 0
|
||||||
|
|||||||
117
server-ltt.sh
117
server-ltt.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-TCP-TLS server builder"
|
>&2 echo "VLESS-TCP-TLS server builder"
|
||||||
echo "Usage: server-ltt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],[proxy_acpt],<d=domain.com>,<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-ltt <c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -33,9 +35,6 @@ do
|
|||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -43,93 +42,73 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo -e "Error: Certhome undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
fullchain="${certhome}/${domain}/fullchain.cer"
|
|
||||||
prvkey="${certhome}/${domain}/${domain}.key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
# inbound frame
|
||||||
echo "TLS cert missing?"
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c ltt.$dest $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
done
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
# Fallback settings
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
for fb in "${fallback[@]}"
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
do
|
if [ -z "${email}" ]; then email="${uid}@ltt.$domain"; fi
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# StreamSettings
|
# StreamSettings
|
||||||
if [ -n "${acceptProxyProtocol}" ]; then
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"sockopt":{"acceptProxyProtocol":true}} ' \
|
|
||||||
|sponge $XCONF
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Network settings
|
# Network settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"network":"tcp"}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \
|
|
||||||
|sponge $XCONF
|
|
||||||
|
|
||||||
# TLS settings
|
# Security settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"tls"} ' \
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|sponge $XCONF
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
# Fallback settings
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"tlsSettings":{}} ' \
|
for fb in "${fallback[@]}"
|
||||||
|sponge $XCONF
|
do
|
||||||
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
|
done
|
||||||
|
|
||||||
cat $XCONF |jq --arg port "${port}" --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
echo $inbound
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings.tlsSettings ) += {"certificates":[{"certificateFile":$fullchain, "keyFile":$prvkey}]} ' \
|
exit 0
|
||||||
|sponge $XCONF
|
|
||||||
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-WS-PLAIN server builder"
|
>&2 echo "VLESS-WS-PLAIN server builder"
|
||||||
echo "Usage: server-lwp <x=xray-config-file>,<p=listen-port>,<w=wskpath>,<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-lwp <w=wskpath>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -15,67 +17,85 @@ do
|
|||||||
d|domain)
|
d|domain)
|
||||||
domain="${kv[1]}"
|
domain="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
w|wpath)
|
w|wpath)
|
||||||
wspath="${kv[1]}"
|
wspath="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${wspath}" ]; then
|
if [ -z "${wspath}" ]; then
|
||||||
echo "Error: wspath undefined."
|
>&2 echo -e "Error: wspath undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
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
|
# inbound frame
|
||||||
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lwp.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@lwp.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
# StreamSettings
|
||||||
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}}' \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|sponge $XCONF
|
fi
|
||||||
|
|
||||||
# Plain settings
|
# Network settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c --arg wspath "${wspath}" '.settings.streamSettings += {"network":"ws","wsSettings":{"path":$wspath}}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|
|
||||||
|sponge $XCONF
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"none"}'`
|
||||||
|
|
||||||
|
# Fallback settings
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $inbound
|
||||||
|
exit 0
|
||||||
|
|||||||
124
server-lwt.sh
124
server-lwt.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VLESS-WS-TLS server builder"
|
>&2 echo "VLESS-WS-TLS server 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>..."
|
>&2 echo "Usage: server-lwt <w=wskpath>,<c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -27,15 +29,15 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
w|wpath)
|
w|wpath)
|
||||||
wspath="${kv[1]}"
|
wspath="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -43,92 +45,78 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo -e "Error: Certhome undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${wspath}" ]; then
|
if [ -z "${wspath}" ]; then
|
||||||
echo "Error: wspath undefined."
|
>&2 echo -e "Error: wspath undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
fullchain="${certhome}/${domain}/fullchain.cer"
|
|
||||||
prvkey="${certhome}/${domain}/${domain}.key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
# inbound frame
|
||||||
echo "TLS cert missing?"
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vless","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c lwt.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@lwt.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg wspath "${wspath}" '.settings.streamSettings += {"network":"ws","wsSettings":{"path":$wspath}}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
119
server-mtt.sh
119
server-mtt.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VMESS-TCP-TLS server builder"
|
>&2 echo "VMESS-TCP-TLS server builder"
|
||||||
echo "Usage: server-mtt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-mtt <c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -27,12 +29,12 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -40,86 +42,73 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo -e "Error: Certhome undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
fullchain="${certhome}/${domain}/fullchain.cer"
|
|
||||||
prvkey="${certhome}/${domain}/${domain}.key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
# inbound frame
|
||||||
echo "TLS cert missing?"
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vmess","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c mtt.$dest $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@mtt.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"network":"tcp"}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VMESS-WS-PLAIN server builder"
|
>&2 echo "VMESS-WS-PLAIN server builder"
|
||||||
echo "Usage: server-mwp <x=xray-config-file>,<p=listen-port>,<w=wskpath>,<u=id0>,<u=id1>..."
|
>&2 echo "Usage: server-mwp <w=wskpath>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -15,67 +17,88 @@ do
|
|||||||
d|domain)
|
d|domain)
|
||||||
domain="${kv[1]}"
|
domain="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
w|wpath)
|
w|wpath)
|
||||||
wspath="${kv[1]}"
|
wspath="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${wspath}" ]; then
|
if [ -z "${wspath}" ]; then
|
||||||
echo "Error: wspath undefined."
|
>&2 echo -e "Error: wspath undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric.\n"; exit 1; fi
|
||||||
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
|
# inbound frame
|
||||||
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vmess","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c mwp.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@mwp.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
# StreamSettings
|
||||||
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"ws","wsSettings":{"path":$wspath}}' \
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|sponge $XCONF
|
fi
|
||||||
|
|
||||||
# Plain settings
|
# Network settings
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
inbound=`echo $inbound| jq -c --arg wspath "${wspath}" '.settings.streamSettings += {"network":"ws","wsSettings":{"path":$wspath}}'`
|
||||||
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"security":"none" } ' \
|
|
||||||
|sponge $XCONF
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"none"}'`
|
||||||
|
|
||||||
|
# Fallback settings
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
>&2 echo "Incorrect fallback format: ${fallback}"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $inbound
|
||||||
|
exit 0
|
||||||
|
|||||||
127
server-mwt.sh
127
server-mwt.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "VMESS-WS-TLS server builder"
|
>&2 echo "VMESS-WS-TLS server 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>..."
|
>&2 echo "Usage: server-mwt <w=wskpath>,<c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -27,15 +29,15 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
w|wpath)
|
w|wpath)
|
||||||
wspath="${kv[1]}"
|
wspath="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -43,92 +45,81 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo -e "Error: Certhome undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${wspath}" ]; then
|
if [ -z "${wspath}" ]; then
|
||||||
echo "Error: wspath undefined."
|
>&2 echo -e "Error: wspath undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
fullchain="${certhome}/${domain}/fullchain.cer"
|
|
||||||
prvkey="${certhome}/${domain}/${domain}.key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
# inbound frame
|
||||||
echo "TLS cert missing?"
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"vmess","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/adduser.sh -p $port -u ${xu} -c mwt.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@mwt.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"id":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg wspath "${wspath}" '.settings.streamSettings += {"network":"ws","wsSettings":{"path":$wspath}}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
>&2 echo "Incorrect fallback format: ${fallback}"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
@@ -20,23 +20,23 @@ if [ $? != 0 ] ; then usage; exit 1 ; fi
|
|||||||
eval set -- "$TEMP"
|
eval set -- "$TEMP"
|
||||||
while true ; do
|
while true ; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
# Multiple Nginx domain servers Allowed
|
|
||||||
-n|--ng-server)
|
-n|--ng-server)
|
||||||
|
# Multiple Nginx domain servers Allowed
|
||||||
NGSVR+=("$2")
|
NGSVR+=("$2")
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
# Multiple Nginx proxy locations Allowed
|
|
||||||
-x|--ng-proxy)
|
-x|--ng-proxy)
|
||||||
|
# Multiple Nginx proxy locations Allowed
|
||||||
NGPROXY+=("$2")
|
NGPROXY+=("$2")
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
# Only SINGLE Stream server Allowed
|
|
||||||
-s|--st-server)
|
-s|--st-server)
|
||||||
|
# Only SINGLE Stream server Allowed
|
||||||
STSVR="$2"
|
STSVR="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
# Multiple Nginx SNI map items Allowed
|
|
||||||
-m|--st-map)
|
-m|--st-map)
|
||||||
|
# Multiple Nginx SNI map items Allowed
|
||||||
STMAP+=("$2")
|
STMAP+=("$2")
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
|||||||
119
server-ttt.sh
119
server-ttt.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "TROJAN-TCP-TLS server builder"
|
>&2 echo "TROJAN-TCP-TLS server builder"
|
||||||
echo "Usage: server-ttt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,<d=domain.com>,<u=pw0>,<u=pw1>..."
|
>&2 echo "Usage: server-ttt <c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user|u=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -27,12 +29,12 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -40,86 +42,73 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo -e "Error: Certhome undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo -e "Error: Domain undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo -e "Error: Port undefined.\n"
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo -e "Error: User undefined.\n"
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${certhome}/${domain}/fullchain.cer" ] && [ -f "${certhome}/${domain}/${domain}.key" ]; then
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo -e "Error: Port number must be numeric.\n"; exit 1; fi
|
||||||
fullchain="${certhome}/${domain}/fullchain.cer"
|
|
||||||
prvkey="${certhome}/${domain}/${domain}.key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${fullchain}" ] || [ ! -f "${prvkey}" ]; then
|
# inbound frame
|
||||||
echo "TLS cert missing?"
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"trojan","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/addusertj.sh -p $port -u ${xu} -c ttt.$dest $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@ttt.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"password":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"network":"tcp"}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then >&2 echo "Incorrect fallback format: ${fallback}"; usage; exit 1; fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
109
server-twp.sh
109
server-twp.sh
@@ -3,8 +3,111 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "TROJAN-WS-PLAIN server builder"
|
>&2 echo "TROJAN-WS-PLAIN server builder"
|
||||||
echo "Usage: server-twp <x=xray-config-file>,<p=listen-port>,<w=wskpath>,<u=pw0>,<u=pw1>..."
|
>&2 echo "Usage: server-twp <w=wskpath>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user=<uid>[:level:email]"
|
||||||
|
}
|
||||||
|
|
||||||
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
|
for option in "${options[@]}"
|
||||||
|
do
|
||||||
|
kv=(`echo $option |tr '=' ' '`)
|
||||||
|
case "${kv[0]}" in
|
||||||
|
d|domain)
|
||||||
|
domain="${kv[1]}"
|
||||||
|
;;
|
||||||
|
f|fallback)
|
||||||
|
fallback+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
p|port)
|
||||||
|
port="${kv[1]}"
|
||||||
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
|
u|user)
|
||||||
|
xuser+=("${kv[1]}")
|
||||||
|
;;
|
||||||
|
w|wpath)
|
||||||
|
wspath="${kv[1]}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${domain}" ]; then
|
||||||
|
>&2 echo "Error: Domain undefined."
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${port}" ]; then
|
||||||
|
>&2 echo "Error: Port undefined."
|
||||||
|
usage; exit 1 ;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${wspath}" ]; then
|
||||||
|
>&2 echo "Error: wspath undefined."
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${xuser}" ]; then
|
||||||
|
>&2 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
|
||||||
|
|
||||||
|
# inbound frame
|
||||||
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"trojan","settings":{"decryption":"none"}}'`
|
||||||
|
|
||||||
|
# User settings
|
||||||
|
for user in "${xuser[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@twp.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"password":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg wspath "${wspath}" '.settings.streamSettings += {"network":"ws","wsSettings":{"path":$wspath}}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"none"}'`
|
||||||
|
|
||||||
|
# Fallback settings
|
||||||
|
for fb in "${fallback[@]}"
|
||||||
|
do
|
||||||
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
>&2 echo "Incorrect fallback format: ${fallback}"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $inbound
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -61,7 +164,7 @@ XCONF=$xconf
|
|||||||
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
|
cat $XCONF |jq --arg port "${port}" 'del( .inbounds[] | select(.port == ($port|tonumber)) )' |sponge $XCONF
|
||||||
|
|
||||||
# Add inbound element
|
# 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 +=[{"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
|
cat $XCONF |jq --arg port "${port}" '( .inbounds[] | select(.port == ($port|tonumber)) | .settings.decryption ) += "none" ' |sponge $XCONF
|
||||||
|
|
||||||
# User settings
|
# User settings
|
||||||
|
|||||||
125
server-twt.sh
125
server-twt.sh
@@ -3,8 +3,10 @@
|
|||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "TROJAN-WS-TLS server builder"
|
>&2 echo "TROJAN-WS-TLS server 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>..."
|
>&2 echo "Usage: server-twt <w=wskpath>,<c=certhome-dir>,<d=domain.com>,<p=listen-port>,<u=id0>,<u=id1>...,[proxy_acpt],[fallback=host:port:path],[xtls]"
|
||||||
|
>&2 echo "Fallback format: fallback=[host]<:port>[:/path] Like: 'baidu.com:443:/path', ':1443:/path', ':1443'"
|
||||||
|
>&2 echo "User format: user=<uid>[:level:email]"
|
||||||
}
|
}
|
||||||
|
|
||||||
options=(`echo $1 |tr ',' ' '`)
|
options=(`echo $1 |tr ',' ' '`)
|
||||||
@@ -27,15 +29,15 @@ do
|
|||||||
p|port)
|
p|port)
|
||||||
port="${kv[1]}"
|
port="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
|
proxy_acpt)
|
||||||
|
acceptProxyProtocol=true
|
||||||
|
;;
|
||||||
u|user)
|
u|user)
|
||||||
xuser+=("${kv[1]}")
|
xuser+=("${kv[1]}")
|
||||||
;;
|
;;
|
||||||
w|wpath)
|
w|wpath)
|
||||||
wspath="${kv[1]}"
|
wspath="${kv[1]}"
|
||||||
;;
|
;;
|
||||||
x|xconf)
|
|
||||||
xconf="${kv[1]}"
|
|
||||||
;;
|
|
||||||
xtls)
|
xtls)
|
||||||
flow="xtls-rprx-vision"
|
flow="xtls-rprx-vision"
|
||||||
;;
|
;;
|
||||||
@@ -43,92 +45,81 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${certhome}" ]; then
|
if [ -z "${certhome}" ]; then
|
||||||
echo "Error: certhome undefined."
|
>&2 echo "Error: Certhome undefined."
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "Error: domain undefined."
|
>&2 echo "Error: Domain undefined."
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${flow}" ]; then
|
|
||||||
flowopt="-f ${flow}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${port}" ]; then
|
if [ -z "${port}" ]; then
|
||||||
echo "Error: port undefined."
|
>&2 echo "Error: Port undefined."
|
||||||
usage
|
usage; exit 1 ;
|
||||||
exit 1 ;
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${wspath}" ]; then
|
if [ -z "${wspath}" ]; then
|
||||||
echo "Error: wspath undefined."
|
>&2 echo "Error: wspath undefined."
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xuser}" ]; then
|
if [ -z "${xuser}" ]; then
|
||||||
echo "Error: user undefined."
|
>&2 echo "Error: User undefined."
|
||||||
usage
|
usage; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${xconf}" ]; then
|
fullchain="${certhome}/${domain}/fullchain.cer"
|
||||||
echo "Error: xconf undefined."
|
prvkey="${certhome}/${domain}/${domain}.key"
|
||||||
usage
|
if [ ! -f "${fullchain}" ]; then >&2 echo "Warning, Fullchain not found: ${fullchain}"; fi
|
||||||
exit 1
|
if [ ! -f "${prvkey}" ]; then >&2 echo "Warning, Private key not found: ${prvkey}"; fi
|
||||||
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
|
if ! [ "${port}" -eq "${port}" ] 2>/dev/null; then >&2 echo "Port number must be numeric"; exit 1; fi
|
||||||
|
|
||||||
XCONF=$xconf
|
# inbound frame
|
||||||
# Remove existing port number if existing.
|
inbound=`jq -nc --arg port "${port}" '{"port":$port,"protocol":"trojan","settings":{"decryption":"none"}}'`
|
||||||
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
|
# User settings
|
||||||
for xu in "${xuser[@]}"
|
for user in "${xuser[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF | ${DIR}/addusertj.sh -p $port -u ${xu} -c twt.$domain $flowopt | sponge $XCONF
|
IFS=':'; uopt=(${user}); uopt=(${uopt[@]})
|
||||||
|
uid="${uopt[0]}"; level="${uopt[1]}"; email="${uopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${uid}" ]; then >&2 echo "Incorrect user format: $user"; usage; exit 1; fi
|
||||||
|
if [ -z "${level}" ]; then level=0; fi
|
||||||
|
if [ -z "${email}" ]; then email="${uid}@twt.$domain"; fi
|
||||||
|
inbound=`echo $inbound| jq -c --arg uid "${uid}" --arg flow "${flow}" --arg level "${level}" --arg email "${email}" \
|
||||||
|
'.settings.clients += [{"password":$uid,"level":($level|tonumber),"email":$email,"flow":$flow}]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# StreamSettings
|
||||||
|
if [ -n "${acceptProxyProtocol}" ]; then
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings.sockopt += {"acceptProxyProtocol":true}'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
inbound=`echo $inbound| jq -c --arg wspath "${wspath}" '.settings.streamSettings += {"network":"ws","wsSettings":{"path":$wspath}}'`
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
inbound=`echo $inbound| jq -c '.settings.streamSettings += {"security":"tls"}'`
|
||||||
|
inbound=`echo $inbound| jq -c --arg fullchain "${fullchain}" --arg prvkey "${prvkey}" \
|
||||||
|
'.settings.streamSettings.tlsSettings += {"certificates":[{"certificateFile":$fullchain,"keyFile":$prvkey}]}'`
|
||||||
|
|
||||||
# Fallback settings
|
# Fallback settings
|
||||||
for fb in "${fallback[@]}"
|
for fb in "${fallback[@]}"
|
||||||
do
|
do
|
||||||
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
|
IFS=':'; fopt=(${fb}); fopt=(${fopt[@]})
|
||||||
|
fhost="${fopt[0]}"; fport="${fopt[1]}"; fpath="${fopt[2]}"
|
||||||
|
unset IFS
|
||||||
|
if [ -z "${fport}" ]; then
|
||||||
|
>&2 echo "Incorrect fallback format: ${fallback}"
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${fhost}" ]; then fhost="127.0.0.1"; fi
|
||||||
|
fdest="$fhost:$fport"
|
||||||
|
Jfb=`jq -nc --arg fdest "${fdest}" --arg fpath "${fpath}" '. |= {"dest":$fdest,"path":$fpath,"xver":1}'`
|
||||||
|
inbound=`echo $inbound| jq -c --argjson Jfb "${Jfb}" '.settings.fallbacks += [$Jfb]'`
|
||||||
done
|
done
|
||||||
|
|
||||||
# Network settings
|
echo $inbound
|
||||||
cat $XCONF |jq --arg port "${port}" --arg wspath "${wspath}" \
|
exit 0
|
||||||
'( .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
|
|
||||||
|
|||||||
Reference in New Issue
Block a user