feat: publish generic Telegram WEB proxy stack
This commit is contained in:
Executable
+145
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
umask 077
|
||||
|
||||
hostname_value="${TPROXY_HOSTNAME:-}"
|
||||
public_ip="${MTPROXY_PUBLIC_IP:-}"
|
||||
workers="${MTPROXY_WORKERS:-1}"
|
||||
max_connections="${MTPROXY_MAX_CONNECTIONS:-4096}"
|
||||
|
||||
if [[ ! "$hostname_value" =~ ^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$ ]] ||
|
||||
[[ "$hostname_value" != *.* ]]; then
|
||||
echo "TPROXY_HOSTNAME must be a lowercase DNS hostname" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
valid_ipv4() {
|
||||
local ip=$1 octet
|
||||
local -a octets
|
||||
local IFS=.
|
||||
read -r -a octets <<<"$ip"
|
||||
[[ ${#octets[@]} -eq 4 ]] || return 1
|
||||
for octet in "${octets[@]}"; do
|
||||
[[ "$octet" =~ ^[0-9]{1,3}$ ]] || return 1
|
||||
((10#$octet <= 255)) || return 1
|
||||
done
|
||||
}
|
||||
|
||||
if ! valid_ipv4 "$public_ip"; then
|
||||
echo "MTPROXY_PUBLIC_IP must be a public IPv4 address" >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ ! "$workers" =~ ^[1-9][0-9]*$ ]] || ((workers > 256)); then
|
||||
echo "MTPROXY_WORKERS must be between 1 and 256" >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ ! "$max_connections" =~ ^[1-9][0-9]*$ ]]; then
|
||||
echo "MTPROXY_MAX_CONNECTIONS must be positive" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
install -d -o root -g root -m 0700 /data/mtproxy
|
||||
install -d -o tproxy -g tproxy -m 0700 /data/tproxy /run/tproxy
|
||||
|
||||
atomic_download() {
|
||||
local url=$1 destination=$2 minimum_size=$3 required_pattern=$4 temporary
|
||||
temporary="${destination}.new"
|
||||
rm -f "$temporary"
|
||||
curl --fail --silent --show-error --location \
|
||||
--proto '=https' --proto-redir '=https' --tlsv1.2 \
|
||||
--output "$temporary" "$url"
|
||||
[[ $(wc -c <"$temporary") -ge $minimum_size ]]
|
||||
grep -q "$required_pattern" "$temporary"
|
||||
chmod 0600 "$temporary"
|
||||
mv -f "$temporary" "$destination"
|
||||
}
|
||||
|
||||
atomic_download \
|
||||
https://core.telegram.org/getProxySecret \
|
||||
/data/mtproxy/proxy-secret 128 '.'
|
||||
atomic_download \
|
||||
https://core.telegram.org/getProxyConfig \
|
||||
/data/mtproxy/proxy-multi.conf 100 '^proxy_for '
|
||||
chown root:mtproxy /data/mtproxy/proxy-secret /data/mtproxy/proxy-multi.conf
|
||||
chmod 0640 /data/mtproxy/proxy-secret /data/mtproxy/proxy-multi.conf
|
||||
|
||||
if [[ ! -s /data/client-secret ]]; then
|
||||
openssl rand -hex 16 > /data/client-secret
|
||||
fi
|
||||
client_secret="$(tr -d '\r\n' </data/client-secret)"
|
||||
if [[ ! "$client_secret" =~ ^[0-9a-f]{32}$ ]]; then
|
||||
echo "persisted client secret is invalid" >&2
|
||||
exit 2
|
||||
fi
|
||||
chown root:root /data/client-secret
|
||||
chmod 0600 /data/client-secret
|
||||
|
||||
if [[ ! -s /data/tproxy/token.key ]]; then
|
||||
head -c 32 /dev/urandom > /data/tproxy/token.key
|
||||
fi
|
||||
chown tproxy:tproxy /data/tproxy/token.key
|
||||
chmod 0400 /data/tproxy/token.key
|
||||
|
||||
cat > /data/tproxy/config.json <<JSON
|
||||
{
|
||||
"public_hostname": "$hostname_value",
|
||||
"base_path": "",
|
||||
"listen": "127.0.0.1:8080",
|
||||
"admin_listen": "127.0.0.1:8081",
|
||||
"public_dir": "/srv/tproxy-site",
|
||||
"token_key_file": "/data/tproxy/token.key",
|
||||
"static_routes": "exact",
|
||||
"profiles_file": "/run/tproxy/profiles.json",
|
||||
"enable_pprof": false
|
||||
}
|
||||
JSON
|
||||
|
||||
cat > /run/tproxy/profiles.json <<JSON
|
||||
{"profiles":[{"name":"default","secret":"$client_secret","backend":"127.0.0.1:2398","carrier_mode":"websocket"}]}
|
||||
JSON
|
||||
|
||||
chown tproxy:tproxy /data/tproxy/config.json /run/tproxy/profiles.json
|
||||
chmod 0400 /data/tproxy/config.json /run/tproxy/profiles.json
|
||||
|
||||
runuser -u tproxy -- /usr/local/bin/tproxy-server \
|
||||
-config /data/tproxy/config.json \
|
||||
-profiles-file /run/tproxy/profiles.json -check
|
||||
|
||||
local_ip="$(hostname -I | tr ' ' '\n' | awk '/^[0-9]+\./ {print; exit}')"
|
||||
if ! valid_ipv4 "$local_ip"; then
|
||||
echo "could not determine the container IPv4 address" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
/usr/local/bin/mtproto-proxy \
|
||||
-u mtproxy \
|
||||
-p 8888 \
|
||||
-H 2398 \
|
||||
-S "$client_secret" \
|
||||
--nat-info "$local_ip:$public_ip" \
|
||||
--aes-pwd /data/mtproxy/proxy-secret /data/mtproxy/proxy-multi.conf \
|
||||
-M "$workers" \
|
||||
-C "$max_connections" &
|
||||
mtproxy_pid=$!
|
||||
|
||||
runuser -u tproxy -- /usr/local/bin/tproxy-server \
|
||||
-config /data/tproxy/config.json &
|
||||
relay_pid=$!
|
||||
|
||||
runuser -u tproxy -- env TPROXY_HOSTNAME="$hostname_value" \
|
||||
/usr/local/bin/tproxy-ingress &
|
||||
ingress_pid=$!
|
||||
|
||||
stop_all() {
|
||||
trap - EXIT TERM INT
|
||||
kill -TERM "$ingress_pid" "$relay_pid" "$mtproxy_pid" 2>/dev/null || true
|
||||
wait "$ingress_pid" "$relay_pid" "$mtproxy_pid" 2>/dev/null || true
|
||||
}
|
||||
trap stop_all EXIT TERM INT
|
||||
|
||||
set +e
|
||||
wait -n "$mtproxy_pid" "$relay_pid" "$ingress_pid"
|
||||
status=$?
|
||||
set -e
|
||||
exit "$status"
|
||||
Reference in New Issue
Block a user