This repository was archived by the owner on Apr 5, 2026. It is now read-only.
forked from TelegramMessenger/MTProxy
-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathstart.sh
More file actions
215 lines (185 loc) · 6.57 KB
/
Copy pathstart.sh
File metadata and controls
215 lines (185 loc) · 6.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/sh
set -e
# Save original arguments before positional parameters are repurposed for secrets
ORIG_ARGS="$*"
# Direct mode: connect to Telegram DCs without ME relay.
# Must be explicitly enabled. Incompatible with PROXY_TAG.
DIRECT_MODE=${DIRECT_MODE:-false}
# proxy-secret is baked into the image at build time (only needed for ME relay mode)
if [ "$DIRECT_MODE" != "true" ] && [ ! -f proxy-secret ]; then
echo "ERROR: proxy-secret not found. The Docker image may be corrupted." >&2
exit 1
fi
# Download/refresh proxy config to data/ (only in ME relay mode)
if [ "$DIRECT_MODE" != "true" ]; then
CONFIG_PATH="data/proxy-multi.conf"
NEEDS_DOWNLOAD=0
if [ ! -f "$CONFIG_PATH" ]; then
NEEDS_DOWNLOAD=1
elif [ $(find "$CONFIG_PATH" -mtime +1 2>/dev/null | wc -l) -gt 0 ]; then
NEEDS_DOWNLOAD=1
fi
PROXY_CONFIG_URL=${PROXY_CONFIG_URL:-https://core.telegram.org/getProxyConfig}
if [ "$NEEDS_DOWNLOAD" -eq 1 ]; then
echo "Downloading proxy config from $PROXY_CONFIG_URL..."
if curl --connect-timeout 10 --max-time 30 --retry 3 --retry-delay 2 -fsSL "$PROXY_CONFIG_URL" -o "$CONFIG_PATH.tmp"; then
mv "$CONFIG_PATH.tmp" "$CONFIG_PATH"
echo "Proxy config downloaded successfully."
else
rm -f "$CONFIG_PATH.tmp"
if [ -f "$CONFIG_PATH" ]; then
echo "WARNING: Failed to refresh proxy config, using cached copy." >&2
else
echo "ERROR: Failed to download proxy config and no cached copy exists." >&2
echo "Ensure core.telegram.org is reachable, or provide proxy-multi.conf in the data/ volume." >&2
exit 1
fi
fi
fi
fi
# Collect secrets from comma-separated SECRET and/or numbered SECRET_N vars.
# Uses positional parameters as a portable array (POSIX sh).
set --
if [ -n "$SECRET" ]; then
_save_ifs="$IFS"
IFS=','
for _s in $SECRET; do
IFS="$_save_ifs"
_s=$(printf '%s' "$_s" | tr -d '[:space:]')
[ -n "$_s" ] && set -- "$@" "$_s"
done
IFS="$_save_ifs"
fi
_i=1
while [ "$_i" -le 16 ]; do
eval "_val=\${SECRET_${_i}:-}"
_val=$(printf '%s' "$_val" | tr -d '[:space:]')
if [ -n "$_val" ]; then
eval "_lbl=\${SECRET_LABEL_${_i}:-}"
_lbl=$(printf '%s' "$_lbl" | tr -d '[:space:]')
eval "_lim=\${SECRET_LIMIT_${_i}:-}"
_lim=$(printf '%s' "$_lim" | tr -d '[:space:]')
_suffix=""
if [ -n "$_lbl" ] || [ -n "$_lim" ]; then
_suffix=":${_lbl}"
fi
if [ -n "$_lim" ]; then
_suffix="${_suffix}:${_lim}"
fi
set -- "$@" "${_val}${_suffix}"
fi
_i=$((_i + 1))
done
if [ "$#" -eq 0 ]; then
echo "No SECRET provided, generating one..."
_gen=$(openssl rand -hex 16)
set -- "$_gen"
echo "Generated secret: $_gen"
fi
if [ "$#" -gt 16 ]; then
echo "ERROR: Maximum 16 secrets supported, got $#" >&2
exit 1
fi
echo "Configured $# secret(s)"
# Set default values
PORT=${PORT:-443}
STATS_PORT=${STATS_PORT:-8888}
WORKERS=${WORKERS:-1}
PROXY_TAG=${PROXY_TAG:-}
RANDOM_PADDING=${RANDOM_PADDING:-}
# Domain or host:port for TLS-transport mode (e.g. google.com or 127.0.0.1:8443)
EE_DOMAIN=${EE_DOMAIN:-}
# Max connections - lower value avoids rlimit issues in containers
MAX_CONNECTIONS=${MAX_CONNECTIONS:-60000}
# Detect container-local IPv4 for NAT.
LOCAL_IP=$(ip -4 route get 8.8.8.8 2>/dev/null | sed -n 's/.* src \([0-9.]*\).*/\1/p')
if [ -z "$LOCAL_IP" ]; then
LOCAL_IP=$(grep -vE '(local|ip6|^fd|^$)' /etc/hosts 2>/dev/null | awk 'NR==1 {print $1}')
fi
# Public IPv4 address to advertise to Telegram DCs.
# Auto-detected if not provided — required for Docker NAT to work.
EXTERNAL_IP=${EXTERNAL_IP:-}
if [ -z "$EXTERNAL_IP" ]; then
EXTERNAL_IP=$(curl -s -4 --connect-timeout 5 --max-time 10 https://icanhazip.com 2>/dev/null || curl -s -4 --connect-timeout 5 --max-time 10 https://ifconfig.me 2>/dev/null || true)
if [ -n "$EXTERNAL_IP" ]; then
echo "Auto-detected external IP: $EXTERNAL_IP"
fi
fi
NAT_INFO_ARGS=""
if [ -n "$EXTERNAL_IP" ] && [ -n "$LOCAL_IP" ]; then
NAT_INFO_ARGS="--nat-info $LOCAL_IP:$EXTERNAL_IP"
elif [ -z "$EXTERNAL_IP" ]; then
echo "WARNING: Could not detect external IP. Set EXTERNAL_IP env var for Docker NAT support." >&2
fi
# Build command
SECRET_ARGS=""
for _s in "$@"; do
SECRET_ARGS="$SECRET_ARGS -S $_s"
done
CMD="./mtproto-proxy -p $STATS_PORT -H $PORT$SECRET_ARGS -c $MAX_CONNECTIONS --http-stats --allow-skip-dh $NAT_INFO_ARGS"
if [ "$PREFER_IPV6" = "true" ]; then
CMD="$CMD -6"
fi
if [ -n "$PROXY_TAG" ]; then
CMD="$CMD -P $PROXY_TAG"
fi
if [ "$RANDOM_PADDING" = "true" ]; then
CMD="$CMD -R"
fi
if [ -n "$EE_DOMAIN" ]; then
CMD="$CMD -D $EE_DOMAIN"
fi
if [ -n "$IP_BLOCKLIST" ]; then
CMD="$CMD --ip-blocklist $IP_BLOCKLIST"
fi
if [ -n "$IP_ALLOWLIST" ]; then
CMD="$CMD --ip-allowlist $IP_ALLOWLIST"
fi
if [ -n "$STATS_ALLOW_NET" ]; then
_save_ifs="$IFS"
IFS=','
for _net in $STATS_ALLOW_NET; do
IFS="$_save_ifs"
_net=$(printf '%s' "$_net" | tr -d '[:space:]')
[ -n "$_net" ] && CMD="$CMD --stats-allow-net $_net"
done
IFS="$_save_ifs"
fi
if [ "$DIRECT_MODE" = "true" ]; then
CMD="$CMD --direct -M $WORKERS -u mtproxy $ORIG_ARGS"
echo "Direct mode: connecting directly to Telegram DCs (no ME relay)"
else
CMD="$CMD --aes-pwd proxy-secret data/proxy-multi.conf -M $WORKERS -u mtproxy $ORIG_ARGS"
fi
echo "Starting MTProxy with command: $CMD"
# Print ready-to-share connection links
echo ""
echo "===== Connection Links ====="
_host="${EXTERNAL_IP:-<YOUR_SERVER_IP>}"
for _s in "$@"; do
# Strip :LABEL:LIMIT suffix for URLs (labels/limits are for the proxy, not for clients)
_secret_hex=$(printf '%s' "$_s" | cut -d: -f1)
_label=$(printf '%s' "$_s" | cut -d: -f2 -s)
if [ -n "$EE_DOMAIN" ]; then
_domain_only=$(printf '%s' "$EE_DOMAIN" | cut -d: -f1)
_domain_hex=$(printf '%s' "$_domain_only" | od -An -tx1 | tr -d ' \n')
_full="ee${_secret_hex}${_domain_hex}"
elif [ "$RANDOM_PADDING" = "true" ]; then
_full="dd${_secret_hex}"
else
_full="$_secret_hex"
fi
_label_display=""
[ -n "$_label" ] && _label_display=" [$_label]"
echo "https://t.me/proxy?server=${_host}&port=${PORT}&secret=${_full}${_label_display}"
done
if [ "$_host" = "<YOUR_SERVER_IP>" ]; then
echo "(Set EXTERNAL_IP to show your server's IP)"
fi
echo "============================="
echo ""
# Start cron daemon for config refresh (only in ME relay mode)
if [ "$DIRECT_MODE" != "true" ]; then
crond
fi
exec $CMD