Skip to content

Instantly share code, notes, and snippets.

@vimagick
Last active March 16, 2024 15:45
Show Gist options
  • Save vimagick/85a5ca5c1f4a06ed9bc5d3d8fb4adfd2 to your computer and use it in GitHub Desktop.
Save vimagick/85a5ca5c1f4a06ed9bc5d3d8fb4adfd2 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -uo pipefail
URI=${1:?uri is empty}
LISTEN_ADDR=127.0.0.1
LISTEN_PORT=1080
CFG_FILE=/tmp/v2ray.json
PID_FILE=/tmp/v2ray.pid
WAIT_TIMEOUT=5
RETRY_COUNT=3
TEST_URL=https://ipinfo.io/
if [[ $URI =~ ^vmess://([0-9A-Za-z/=+]+)$ ]]; then
json=$(echo "${BASH_REMATCH[1]}" | base64 -d 2>/dev/null)
if (($?==0)) && jq -e 'select(.v=="2")' <<< "$json" >/dev/null 2>&1; then
CONFIG=$(echo "$json" | jq '
{
log:{loglevel:"warning"},
inbounds:[{protocol:"socks",listen:"127.0.0.1",port:1080}],
outbounds:[
{
protocol:"vmess",
settings:{
vnext:[
{
address:.add,
port:(.port|tonumber),
users:[
{
id:.id,
alterId:(.aid|tonumber),
security:(.scy // "zero")
}
]
}
]
},
streamSettings:{
network:.net,
security:(if .tls=="" then "none" else .tls end),
tlsSettings:{serverName:.sni,allowInsecure:true},
wsSettings:{path:.path,headers:{Host:.host}}
},
mux:{enabled:true}
}
]
} | if .outbounds[0].streamSettings.network=="tcp" then del(.outbounds[0].streamSettings.wsSettings) end
| if .outbounds[0].streamSettings.security=="none" then del(.outbounds[0].streamSettings.tlsSettings) end')
else
echo "ERROR: cannot decode uri" >&2
exit 2
fi
elif [[ $URI =~ ^vless://(.+)@(.+):([0-9]+)\?(.+)$ ]]; then
json=$(trurl --json "$URI" | jq '.[0] | .params |= from_entries')
if (($?==0)); then
CONFIG=$(echo "$json" | jq '
{
log:{loglevel:"warning"},
inbounds:[{protocol:"socks",listen:"127.0.0.1",port:1080}],
outbounds:[
{
protocol:"vless",
settings:{
vnext:[
{
address:(.parts.host),
port:(.parts.port|tonumber),
users:[
{
id:(.parts.user),
encryption:(.params.encryption),
flow:"xtls-rprx-vision",
level:0
}
]
}
]
},
streamSettings:{
network:.params.type,
security:(if .params.security=="" then "none" else .params.security end),
tlsSettings:{serverName:.params.sni,allowInsecure:true},
wsSettings:{path:.params.path,headers:{Host:.params.sni}}
},
mux:{enabled:true}
}
]
} | if .outbounds[0].streamSettings.network=="tcp" then del(.outbounds[0].streamSettings.wsSettings) end
| if .outbounds[0].streamSettings.security=="none" then del(.outbounds[0].streamSettings.tlsSettings) end')
else
echo "ERROR: cannot decode uri" >&2
exit 2
fi
elif [[ $URI =~ ^trojan://(.+)@(.+):([0-9]+)\?(.+)$ ]]; then
json=$(trurl --json "$URI" | jq '.[0] | .params |= from_entries')
if (($?==0)); then
CONFIG=$(echo "$json" | jq '
{
log:{loglevel:"warning"},
inbounds:[{protocol:"socks",listen:"127.0.0.1",port:1080}],
outbounds:[
{
protocol:"trojan",
settings:{
servers:[
{
address:(.parts.host),
port:(.parts.port|tonumber),
password:(.parts.user),
level:0
}
]
},
streamSettings:{
network:(.params.type//"tcp"),
security:"tls",
tlsSettings:{serverName:.params.sni,allowInsecure:(if .params.allowInsecure=="1" then true else false end)},
wsSettings:{path:.params.path,headers:{Host:.params.sni}}
},
mux:{enabled:true}
}
]
} | if .outbounds[0].streamSettings.network=="tcp" then del(.outbounds[0].streamSettings.wsSettings) end')
else
echo "ERROR: cannot decode uri" >&2
exit 2
fi
elif [[ $URI =~ ^ss://(.+)@(.+):([0-9]+)$ ]]; then
json=$(trurl --json "$URI" | jq '.[0]')
if (($?==0)); then
account=($(echo "$json" | jq -r '.parts.user|@base64d|split(":")|@tsv'))
if ((${#account[@]}!=2)); then
echo "ERROR: cannot decode uri" >&2
exit 2
fi
CONFIG=$(echo "$json" | jq --arg method "${account[0]}" --arg password "${account[1]}" '
{
log:{loglevel:"warning"},
inbounds:[{protocol:"socks",listen:"127.0.0.1",port:1080}],
outbounds:[
{
protocol:"shadowsocks",
settings:{
servers:[
{
address:(.parts.host),
port:(.parts.port|tonumber),
method:$method,
password:$password,
ota:false,
level:0
}
]
},
mux:{enabled:true}
}
]
}')
else
echo "ERROR: cannot decode uri" >&2
exit 2
fi
else
echo "ERROR: bad uri prefix" >&2
exit 1
fi
if lsof -nP -iTCP:$LISTEN_PORT -s TCP:listen; then
echo "ERROR: failed to listen on $LISTEN_ADDR:$LISTEN_PORT" >&2
exit 3
fi
echo "$CONFIG" > $CFG_FILE
if ! v2ray test -c $CFG_FILE >/dev/null 2>&1; then
echo "ERROR: bad config" >&2
exit 4
fi
v2ray run -c $CFG_FILE >/dev/null 2>&1 &
echo $! > $PID_FILE
trap "kill $(cat $PID_FILE)" SIGINT SIGTERM EXIT
sleep $WAIT_TIMEOUT
if curl -s -f -m $WAIT_TIMEOUT -w '\n' -x socks5h://$LISTEN_ADDR:$LISTEN_PORT $TEST_URL >/dev/null 2>&1; then
echo "$CONFIG" | jq -c .
exit 0
else
echo "ERROR: test failed" >&2
exit 5
fi
@vimagick
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment