MTProto
This commit is contained in:
@@ -6,6 +6,9 @@ indent_size=4
|
||||
end_of_line=lf
|
||||
charset=utf-8
|
||||
trim_trailing_whitespace=true
|
||||
[*.php]
|
||||
insert_final_newline=true
|
||||
[makefile]
|
||||
indent_style=tab
|
||||
[config/Makefile]
|
||||
indent_style=tab
|
||||
|
||||
@@ -2,5 +2,6 @@ TZ=Europe/Samara
|
||||
WGADDRESS=10.0.1.1/24
|
||||
WGPORT=51820
|
||||
SSPORT=8388
|
||||
TGPORT=4443
|
||||
SYSTEM=ubuntu
|
||||
RELEASE=18.04
|
||||
|
||||
+107
-1
@@ -120,6 +120,15 @@ class Bot
|
||||
case preg_match('~^/id$~', $this->input['message'], $m):
|
||||
$this->send($this->input['chat'], $this->input['from'], $this->input['message_id']);
|
||||
break;
|
||||
case preg_match('~^/mtproto$~', $this->input['callback'], $m):
|
||||
$this->mtproto();
|
||||
break;
|
||||
case preg_match('~^/generateSecret$~', $this->input['callback'], $m):
|
||||
$this->generateSecret();
|
||||
break;
|
||||
case preg_match('~^/setSecret$~', $this->input['callback'], $m):
|
||||
$this->setSecret();
|
||||
break;
|
||||
case preg_match('~^/subnet (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->subnet(...explode('_', $m['arg']));
|
||||
break;
|
||||
@@ -277,6 +286,90 @@ class Bot
|
||||
}
|
||||
}
|
||||
|
||||
public function generateSecret()
|
||||
{
|
||||
$this->send($this->input['chat'], trim($this->ssh('head -c 16 /dev/urandom | xxd -ps', 'tg')));
|
||||
}
|
||||
|
||||
public function setSecret()
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
"@{$this->input['username']} enter url",
|
||||
$this->input['message_id'],
|
||||
reply: 'enter url',
|
||||
);
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
'start_callback' => $this->input['callback_id'],
|
||||
'callback' => 'secretSet',
|
||||
'args' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function secretSet($secret)
|
||||
{
|
||||
file_put_contents('/config/mtprotosecret', $secret ?: '');
|
||||
$this->restartTG($secret);
|
||||
$this->mtproto();
|
||||
}
|
||||
|
||||
public function restartTG($secret)
|
||||
{
|
||||
$this->ssh('pkill mtproto-proxy', 'tg');
|
||||
if (preg_match('~^\w{32}$~', $secret)) {
|
||||
$p = getenv('TGPORT');
|
||||
$this->ssh("/MTProxy/objs/bin/mtproto-proxy -u nobody -H $p --nat-info 10.10.0.8:{$this->ip} -S $secret --aes-pwd /proxy-secret /proxy-multi.conf -M 1 >/dev/null 2>&1 &", 'tg');
|
||||
}
|
||||
}
|
||||
|
||||
public function mtproto()
|
||||
{
|
||||
$s = file_get_contents('/config/mtprotosecret');
|
||||
$p = getenv('TGPORT');
|
||||
$ip = $this->getPacConf()['domain'] ?: $this->ip;
|
||||
$st = $this->ssh('pgrep mtproto-proxy', 'tg') ? 'on' : 'off';
|
||||
$text[] = "Menu -> MTProto\n";
|
||||
$text[] = "status: $st\n";
|
||||
if ($st == 'on') {
|
||||
$text[] = "<code>https://t.me/proxy?server=$ip&port=$p&secret=$s</code>\n\n<code>tg://proxy?server=$ip&port=$p&secret=$s</code>";
|
||||
$data[] = [
|
||||
[
|
||||
'text' => "https://t.me/proxy",
|
||||
'url' => "https://t.me/proxy?server=$ip&port=$p&secret=$s",
|
||||
],
|
||||
[
|
||||
'text' => "tg://proxy",
|
||||
'url' => "tg://proxy?server=$ip&port=$p&secret=$s",
|
||||
],
|
||||
];
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('generateSecret'),
|
||||
'callback_data' => "/generateSecret",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('setSecret') . ($s ? ": $s" : ''),
|
||||
'callback_data' => "/setSecret",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/menu",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
$this->input['chat'],
|
||||
$this->input['message_id'],
|
||||
implode("\n", $text ?: ['...']),
|
||||
$data ?: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function setLang($lang)
|
||||
{
|
||||
$conf = $this->getPacConf();
|
||||
@@ -496,6 +589,7 @@ class Bot
|
||||
'private' => file_exists('/certs/cert_private') ? file_get_contents('/certs/cert_private') : false,
|
||||
'public' => file_exists('/certs/cert_public') ? file_get_contents('/certs/cert_public') : false,
|
||||
],
|
||||
'mtproto' => file_get_contents('/config/mtprotosecret'),
|
||||
|
||||
];
|
||||
$this->upload('vpnbot_export_' . date('d_m_Y_H_i') . '.json', json_encode($conf, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
@@ -568,6 +662,12 @@ class Bot
|
||||
file_put_contents('/config/sslocal.json', json_encode($json['sl'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
$this->ssh('/sslocal -v -d -c /config.json', 'proxy');
|
||||
}
|
||||
// mtproto
|
||||
if (!empty($json['mtproto'])) {
|
||||
$out[] = 'update mtproto';
|
||||
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
||||
$this->restartTG($json['mtproto']);
|
||||
}
|
||||
// nginx
|
||||
$out[] = 'reset nginx';
|
||||
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
||||
@@ -2098,7 +2198,7 @@ DNS-over-HTTPS with IP:
|
||||
|
||||
public function i18n(string $menu): string
|
||||
{
|
||||
return $this->i18n[$menu][$this->language] ?: 'no translate';
|
||||
return $this->i18n[$menu][$this->language] ?: $menu;
|
||||
}
|
||||
|
||||
public function menu($type = false, $arg = false, $return = false)
|
||||
@@ -2127,6 +2227,12 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/menu pac",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('mtproto'),
|
||||
'callback_data' => "/mtproto",
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('config'),
|
||||
|
||||
@@ -221,4 +221,16 @@ $i = [
|
||||
'en' => 'calc CIDR',
|
||||
'ru' => 'calc CIDR',
|
||||
],
|
||||
'mtproto' => [
|
||||
'en' => 'MTProto',
|
||||
'ru' => 'MTProto',
|
||||
],
|
||||
'generateSecret' => [
|
||||
'en' => 'generateSecret',
|
||||
'ru' => 'сгенерировать ключ',
|
||||
],
|
||||
'setSecret' => [
|
||||
'en' => 'setSecret',
|
||||
'ru' => 'установить ключ',
|
||||
],
|
||||
];
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
OBJ = objs
|
||||
DEP = dep
|
||||
EXE = ${OBJ}/bin
|
||||
|
||||
COMMIT := $(shell git log -1 --pretty=format:"%H")
|
||||
|
||||
ARCH =
|
||||
ifeq ($m, 32)
|
||||
ARCH = -m32
|
||||
endif
|
||||
ifeq ($m, 64)
|
||||
ARCH = -m64
|
||||
endif
|
||||
|
||||
CFLAGS = $(ARCH) -O3 -std=gnu11 -Wall -mpclmul -march=core2 -mfpmath=sse -mssse3 -fno-strict-aliasing -fno-strict-overflow -fwrapv -DAES=1 -DCOMMIT=\"${COMMIT}\" -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 -fcommon
|
||||
LDFLAGS = $(ARCH) -ggdb -rdynamic -lm -lrt -lcrypto -lz -lpthread -lcrypto
|
||||
|
||||
LIB = ${OBJ}/lib
|
||||
CINCLUDE = -iquote common -iquote .
|
||||
|
||||
LIBLIST = ${LIB}/libkdb.a
|
||||
|
||||
PROJECTS = common jobs mtproto net crypto engine
|
||||
|
||||
OBJDIRS := ${OBJ} $(addprefix ${OBJ}/,${PROJECTS}) ${EXE} ${LIB}
|
||||
DEPDIRS := ${DEP} $(addprefix ${DEP}/,${PROJECTS})
|
||||
ALLDIRS := ${DEPDIRS} ${OBJDIRS}
|
||||
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
EXELIST := ${EXE}/mtproto-proxy
|
||||
|
||||
|
||||
OBJECTS = \
|
||||
${OBJ}/mtproto/mtproto-proxy.o ${OBJ}/mtproto/mtproto-config.o ${OBJ}/net/net-tcp-rpc-ext-server.o
|
||||
|
||||
DEPENDENCE_CXX := $(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${OBJECTS_CXX}))
|
||||
DEPENDENCE_STRANGE := $(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${OBJECTS_STRANGE}))
|
||||
DEPENDENCE_NORM := $(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${OBJECTS}))
|
||||
|
||||
LIB_OBJS_NORMAL := \
|
||||
${OBJ}/common/crc32c.o \
|
||||
${OBJ}/common/pid.o \
|
||||
${OBJ}/common/sha1.o \
|
||||
${OBJ}/common/sha256.o \
|
||||
${OBJ}/common/md5.o \
|
||||
${OBJ}/common/resolver.o \
|
||||
${OBJ}/common/parse-config.o \
|
||||
${OBJ}/crypto/aesni256.o \
|
||||
${OBJ}/jobs/jobs.o ${OBJ}/common/mp-queue.o \
|
||||
${OBJ}/net/net-events.o ${OBJ}/net/net-msg.o ${OBJ}/net/net-msg-buffers.o \
|
||||
${OBJ}/net/net-config.o ${OBJ}/net/net-crypto-aes.o ${OBJ}/net/net-crypto-dh.o ${OBJ}/net/net-timers.o \
|
||||
${OBJ}/net/net-connections.o \
|
||||
${OBJ}/net/net-rpc-targets.o \
|
||||
${OBJ}/net/net-tcp-connections.o ${OBJ}/net/net-tcp-rpc-common.o ${OBJ}/net/net-tcp-rpc-client.o ${OBJ}/net/net-tcp-rpc-server.o \
|
||||
${OBJ}/net/net-http-server.o \
|
||||
${OBJ}/common/tl-parse.o ${OBJ}/common/common-stats.o \
|
||||
${OBJ}/engine/engine.o ${OBJ}/engine/engine-signals.o \
|
||||
${OBJ}/engine/engine-net.o \
|
||||
${OBJ}/engine/engine-rpc.o \
|
||||
${OBJ}/engine/engine-rpc-common.o \
|
||||
${OBJ}/net/net-thread.o ${OBJ}/net/net-stats.o ${OBJ}/common/proc-stat.o \
|
||||
${OBJ}/common/kprintf.o \
|
||||
${OBJ}/common/precise-time.o ${OBJ}/common/cpuid.o \
|
||||
${OBJ}/common/server-functions.o ${OBJ}/common/crc32.o \
|
||||
|
||||
LIB_OBJS := ${LIB_OBJS_NORMAL}
|
||||
|
||||
DEPENDENCE_LIB := $(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${LIB_OBJS}))
|
||||
|
||||
DEPENDENCE_ALL := ${DEPENDENCE_NORM} ${DEPENDENCE_STRANGE} ${DEPENDENCE_LIB}
|
||||
|
||||
OBJECTS_ALL := ${OBJECTS} ${LIB_OBJS}
|
||||
|
||||
all: ${ALLDIRS} ${EXELIST}
|
||||
dirs: ${ALLDIRS}
|
||||
create_dirs_and_headers: ${ALLDIRS}
|
||||
|
||||
${ALLDIRS}:
|
||||
@test -d $@ || mkdir -p $@
|
||||
|
||||
-include ${DEPENDENCE_ALL}
|
||||
|
||||
${OBJECTS}: ${OBJ}/%.o: %.c | create_dirs_and_headers
|
||||
${CC} ${CFLAGS} ${CINCLUDE} -c -MP -MD -MF ${DEP}/$*.d -MQ ${OBJ}/$*.o -o $@ $<
|
||||
|
||||
${LIB_OBJS_NORMAL}: ${OBJ}/%.o: %.c | create_dirs_and_headers
|
||||
${CC} ${CFLAGS} -fpic ${CINCLUDE} -c -MP -MD -MF ${DEP}/$*.d -MQ ${OBJ}/$*.o -o $@ $<
|
||||
|
||||
${EXELIST}: ${LIBLIST}
|
||||
|
||||
${EXE}/mtproto-proxy: ${OBJ}/mtproto/mtproto-proxy.o ${OBJ}/mtproto/mtproto-config.o ${OBJ}/net/net-tcp-rpc-ext-server.o
|
||||
${CC} -o $@ $^ ${LIB}/libkdb.a ${LDFLAGS}
|
||||
|
||||
${LIB}/libkdb.a: ${LIB_OBJS}
|
||||
rm -f $@ && ar rcs $@ $^
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJ} ${DEP} ${EXE} || true
|
||||
|
||||
force-clean: clean
|
||||
@@ -62,6 +62,7 @@ services:
|
||||
- ./config/nginx_default.conf:/config/nginx_default.conf
|
||||
- ./config/ssserver.json:/config/ssserver.json
|
||||
- ./config/sslocal.json:/config/sslocal.json
|
||||
- ./config/mtprotosecret:/config/mtprotosecret
|
||||
- ./certs/:/certs/
|
||||
- type: volume
|
||||
target: /config/adguard
|
||||
@@ -73,9 +74,11 @@ services:
|
||||
- ./scripts/check_file.sh:/check_file.sh
|
||||
environment:
|
||||
TZ: ${TZ}
|
||||
IP: ${IP}
|
||||
ADDRESS: ${WGADDRESS}
|
||||
WGPORT: ${WGPORT}
|
||||
SSPORT: ${SSPORT}
|
||||
TGPORT: ${TGPORT}
|
||||
hostname: unit
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 1s
|
||||
@@ -204,3 +207,30 @@ services:
|
||||
default:
|
||||
ipv4_address: 10.10.0.6
|
||||
logging: *default-logging
|
||||
tg:
|
||||
build:
|
||||
dockerfile: dockerfile/telegram.dockerfile
|
||||
args:
|
||||
RELEASE: ${RELEASE}
|
||||
SYSTEM: ${SYSTEM}
|
||||
volumes:
|
||||
- ./config/.profile:/root/.bashrc:ro
|
||||
- ./ssh:/ssh
|
||||
- ./scripts/start_tg.sh:/start_tg.sh
|
||||
- ./config/mtprotosecret:/mtprotosecret
|
||||
hostname: telegram
|
||||
depends_on:
|
||||
unit:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- ${TGPORT}:${TGPORT}
|
||||
environment:
|
||||
TZ: ${TZ}
|
||||
IP: ${IP}
|
||||
TGPORT: ${TGPORT}
|
||||
stop_grace_period: 1s
|
||||
command: ["/bin/sh", "/start_tg.sh"]
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: 10.10.0.8
|
||||
logging: *default-logging
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
arg SYSTEM
|
||||
arg RELEASE
|
||||
from ${SYSTEM}:${RELEASE}
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
run apt update && \
|
||||
apt install -y git curl build-essential libssl-dev zlib1g-dev xxd ssh && \
|
||||
apt clean autoclean && \
|
||||
apt autoremove -y && \
|
||||
mkdir /root/.ssh
|
||||
run git clone https://github.com/TelegramMessenger/MTProxy
|
||||
copy config/Makefile /MTProxy/Makefile
|
||||
run cd /MTProxy && make
|
||||
env PATH="$PATH:/MTProxy/objs/bin"
|
||||
|
||||
@@ -5,7 +5,7 @@ hosts: unhosts # маппинг доменов на локалку
|
||||
unhosts:
|
||||
sed -i '/test.ru/d' /mnt/c/Windows/System32/drivers/etc/hosts
|
||||
u: # запуск контейнеров
|
||||
RELEASE=$(shell lsb_release -rs) SYSTEM=$(shell lsb_release -is | tr '[:upper:]' '[:lower:]') docker compose up -d --build --force-recreate
|
||||
IP=$(shell ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$$|\1|p' | awk '{print $1}' | head -1) RELEASE=$(shell lsb_release -rs) SYSTEM=$(shell lsb_release -is | tr '[:upper:]' '[:lower:]') docker compose up -d --build --force-recreate
|
||||
# sleep 1
|
||||
# docker compose logs unit wg ss proxy
|
||||
d: # остановка контейнеров
|
||||
@@ -29,3 +29,5 @@ ad: # консоль сервиса
|
||||
docker compose exec ad bash
|
||||
proxy: # консоль сервиса
|
||||
docker compose exec proxy bash
|
||||
tg: # консоль сервиса
|
||||
docker compose exec tg bash
|
||||
|
||||
@@ -7,6 +7,7 @@ apt install -y \
|
||||
make \
|
||||
git \
|
||||
iptables \
|
||||
iproute2 \
|
||||
xtables-addons-common \
|
||||
xtables-addons-dkms
|
||||
mkdir -p /etc/apt/keyrings
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
cat /ssh/key.pub > /root/.ssh/authorized_keys
|
||||
echo 'HostKeyAlgorithms +ssh-rsa' >> /etc/ssh/sshd_config
|
||||
echo 'PubkeyAcceptedKeyTypes +ssh-rsa' >> /etc/ssh/sshd_config
|
||||
service ssh start
|
||||
curl -s https://core.telegram.org/getProxySecret -o proxy-secret
|
||||
curl -s https://core.telegram.org/getProxyConfig -o proxy-multi.conf
|
||||
if [ $(cat /mtprotosecret | wc -c) -gt 0 ]
|
||||
then
|
||||
SECRET=$(cat /mtprotosecret)
|
||||
mtproto-proxy -u nobody -H $TGPORT --nat-info 10.10.0.8:$IP -S $SECRET --aes-pwd /proxy-secret /proxy-multi.conf -M 1
|
||||
fi
|
||||
tail -f /dev/null
|
||||
@@ -1,4 +1,3 @@
|
||||
export IP=$(curl https://ipinfo.io/ip)
|
||||
rm /ssh/key*
|
||||
ssh-keygen -m PEM -t rsa -f /ssh/key -N ''
|
||||
openssl req -newkey rsa:2048 -sha256 -nodes -x509 -days 365 -keyout /certs/self_private -out /certs/self_public -subj "/C=NN/ST=N/L=N/O=N/CN=$IP"
|
||||
|
||||
Reference in New Issue
Block a user