Compare commits

...

6 Commits

Author SHA1 Message Date
Kira bff67b3ecf Docs/readme docker (#843) 2026-05-13 09:20:10 +03:00
Flowseal d5abfbf9c2 github connection fallback 2026-05-09 16:47:56 +03:00
Flowseal 8269ebe3bb download ways mention on build's page 2026-05-08 20:42:31 +03:00
Flowseal 3770569789 revert version 2026-05-08 14:49:19 +03:00
Flowseal e72a44d74b github downloader fix 2026-05-08 14:36:54 +03:00
deexsed 33d3147c0b fix: автоответы только для label "bug" (#826) 2026-05-08 12:19:20 +03:00
11 changed files with 137 additions and 14 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
name: 🐛 Проблема name: 🐛 Проблема
title: '[Проблема] ' title: '[Проблема] '
description: Сообщить о проблеме description: Сообщить о проблеме
labels: ['type: проблема', 'status: нуждается в сортировке'] labels: ['bug']
body: body:
- type: input - type: input
+1 -1
View File
@@ -1,7 +1,7 @@
name: 🚀 Предложение name: 🚀 Предложение
title: '[Предложение] ' title: '[Предложение] '
description: Предложить улучшение или новую функциональность description: Предложить улучшение или новую функциональность
labels: ['type: предложение', 'status: нуждается в сортировке'] labels: ['enhancement']
body: body:
- type: textarea - type: textarea
+4
View File
@@ -457,6 +457,10 @@ jobs:
body: | body: |
## ##
### [❤️ Поддержать развитие проекта](https://github.com/Flowseal/tg-ws-proxy/blob/main/docs/Funding.md) ### [❤️ Поддержать развитие проекта](https://github.com/Flowseal/tg-ws-proxy/blob/main/docs/Funding.md)
> [!TIP]
> Не можете скачать?
> Добавьте `185.199.109.133 release-assets.githubusercontent.com` в hosts или воспользуйтесь зеркалом: https://sourceforge.net/projects/tg-ws-proxy.mirror/files/
files: | files: |
dist/TgWsProxy_windows.exe dist/TgWsProxy_windows.exe
dist/TgWsProxy_windows_7_64bit.exe dist/TgWsProxy_windows_7_64bit.exe
+1
View File
@@ -9,6 +9,7 @@ permissions:
jobs: jobs:
comment: comment:
if: contains(github.event.issue.labels.*.name, 'bug')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Comment on new issue - name: Comment on new issue
+69
View File
@@ -0,0 +1,69 @@
# TG WS Proxy для Docker
## Установка из исходников
Вводите команды последовательно, одну за другой:
```bash
# Скачиваем репозиторий
git clone https://github.com/Flowseal/tg-ws-proxy.git
# Переходим в папку с проектом
cd tg-ws-proxy
# Собираем образ
docker build -t tg-ws-proxy .
# Запускаем контейнер
docker run -d \
--name tg-ws-proxy \
--restart=always \
-p 1443:1443 \
tg-ws-proxy:latest
# Получаем ссылку для подключения
docker logs tg-ws-proxy 2>&1 | grep 'tg://proxy'
```
После выполнения последней команды вы увидите ссылку вида:
```text
tg://proxy?server=172.17.0.2&port=1443&secret=dd68f127db1d...
```
## Настройка параметров
Все настройки задаются переменными окружения при запуске контейнера:
| Переменная | Описание | По умолчанию |
|-----------------------|------------------------------------------------|--------------------------------------|
| `TG_WS_PROXY_HOST` | Адрес для приёма подключений | `0.0.0.0` |
| `TG_WS_PROXY_PORT` | Порт внутри контейнера | `1443` |
| `TG_WS_PROXY_SECRET` | Секретный ключ | `random` |
| `TG_WS_PROXY_DC_IPS` | Пары «номер DC:IP» через пробел | `2:149.154.167.220 4:149.154.167.220`|
Пример с ручным указанием секрета:
```bash
docker run -d \
--name tg-ws-proxy \
--restart=always \
-p 1443:1443 \
-e TG_WS_PROXY_SECRET="ваш_секрет" \
tg-ws-proxy:latest
```
Для генерации секрета можно использовать:
```bash
openssl rand -hex 16
```
## Настройка Telegram Desktop
1. Telegram → **Настройки** → **Продвинутые настройки** → **Тип подключения** → **Прокси**
2. Добавьте прокси:
- **Тип:** MTProto
- **Сервер:** `127.0.0.1` (или переопределенный вами)
- **Порт:** `1443` (или переопределенный вами)
- **Secret:** из настроек или логов
+1
View File
@@ -34,6 +34,7 @@
- **[Windows](./README.windows.md)** - **[Windows](./README.windows.md)**
- **[macOS](./README.macos.md)** - **[macOS](./README.macos.md)**
- **[Linux](./README.linux.md)** - **[Linux](./README.linux.md)**
- **[Docker](./README.docker.md)**
- [Настройка Cloudflare-домена (CF-прокси)](./CfProxy.md) - [Настройка Cloudflare-домена (CF-прокси)](./CfProxy.md)
- [Fake TLS + upstream в Nginx](./FakeTlsNginx.md) - [Fake TLS + upstream в Nginx](./FakeTlsNginx.md)
- [Файлы конфигурации Tray-приложения](./TrayConfig.md) - [Файлы конфигурации Tray-приложения](./TrayConfig.md)
+2 -2
View File
@@ -1,6 +1,6 @@
from .config import parse_dc_ip_list, proxy_config from .config import parse_dc_ip_list, proxy_config
from .utils import get_link_host from .utils import get_link_host, build_github_opener
__version__ = "1.6.6" __version__ = "1.6.6"
__all__ = ["__version__", "get_link_host", "proxy_config", "parse_dc_ip_list"] __all__ = ["__version__", "get_link_host", "proxy_config", "parse_dc_ip_list", "build_github_opener"]
+3 -2
View File
@@ -7,9 +7,10 @@ import threading
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Dict, List from typing import Dict, List
from urllib.request import Request, urlopen from urllib.request import Request
from .balancer import balancer from .balancer import balancer
from .utils import build_github_opener
log = logging.getLogger('tg-mtproto-proxy') log = logging.getLogger('tg-mtproto-proxy')
@@ -70,7 +71,7 @@ def _fetch_cfproxy_domain_list() -> List[str]:
try: try:
req = Request(CFPROXY_DOMAINS_URL + "?" + "".join(random.choices(string.ascii_letters, k=7)), req = Request(CFPROXY_DOMAINS_URL + "?" + "".join(random.choices(string.ascii_letters, k=7)),
headers={'User-Agent': 'tg-ws-proxy'}) headers={'User-Agent': 'tg-ws-proxy'})
with urlopen(req, timeout=10) as resp: with build_github_opener().open(req, timeout=10) as resp:
text = resp.read().decode('utf-8', errors='replace') text = resp.read().decode('utf-8', errors='replace')
encoded = [ encoded = [
line.strip() for line in text.splitlines() line.strip() for line in text.splitlines()
+41 -2
View File
@@ -1,6 +1,9 @@
import socket as _socket import socket as _socket
import urllib.request
import http.client
from typing import Optional from typing import Optional, Dict
from urllib.request import Request
ZERO_64 = b'\x00' * 64 ZERO_64 = b'\x00' * 64
@@ -26,6 +29,11 @@ RESERVED_STARTS = {b'\x48\x45\x41\x44', b'\x50\x4F\x53\x54',
b'\xdd\xdd\xdd\xdd', b'\x16\x03\x01\x02'} b'\xdd\xdd\xdd\xdd', b'\x16\x03\x01\x02'}
RESERVED_CONTINUE = b'\x00\x00\x00\x00' RESERVED_CONTINUE = b'\x00\x00\x00\x00'
_GITHUB_IPS: Dict[str, str] = {
"release-assets.githubusercontent.com": "185.199.109.133",
"raw.githubusercontent.com": "185.199.109.133",
}
def human_bytes(n: int) -> str: def human_bytes(n: int) -> str:
for unit in ('B', 'KB', 'MB', 'GB'): for unit in ('B', 'KB', 'MB', 'GB'):
@@ -45,4 +53,35 @@ def get_link_host(host: str) -> Optional[str]:
link_host = '127.0.0.1' link_host = '127.0.0.1'
return link_host return link_host
else: else:
return host return host
class _PinnedHTTPSHandler(urllib.request.HTTPSHandler):
def https_open(self, req: Request):
host = req.host.split(":")[0]
ip = _GITHUB_IPS.get(host)
if not ip:
return super().https_open(req)
pinned = ip
class _Conn(http.client.HTTPSConnection):
def connect(self):
self.sock = _socket.create_connection(
(pinned, self.port or 443),
self.timeout,
self.source_address,
)
if self._tunnel_host:
self._tunnel()
self.sock = self._context.wrap_socket(
self.sock, server_hostname=self._tunnel_host or self.host
)
try:
return self.do_open(_Conn, req)
except Exception:
return super().https_open(req)
def build_github_opener() -> urllib.request.OpenerDirector:
return urllib.request.build_opener(_PinnedHTTPSHandler())
+3 -2
View File
@@ -14,7 +14,8 @@ from itertools import zip_longest
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Optional, Tuple from typing import Any, Dict, Optional, Tuple
from urllib.error import HTTPError, URLError from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen from urllib.request import Request
from proxy.utils import build_github_opener
REPO = "Flowseal/tg-ws-proxy" REPO = "Flowseal/tg-ws-proxy"
RELEASES_LATEST_API = f"https://api.github.com/repos/{REPO}/releases/latest" RELEASES_LATEST_API = f"https://api.github.com/repos/{REPO}/releases/latest"
@@ -135,7 +136,7 @@ def fetch_latest_release(
method="GET", method="GET",
) )
try: try:
with urlopen(req, timeout=timeout) as resp: with build_github_opener().open(req, timeout=timeout) as resp:
code = getattr(resp, "status", None) or resp.getcode() code = getattr(resp, "status", None) or resp.getcode()
new_etag = resp.headers.get("ETag") new_etag = resp.headers.get("ETag")
raw = resp.read().decode("utf-8", errors="replace") raw = resp.read().decode("utf-8", errors="replace")
+11 -4
View File
@@ -8,8 +8,11 @@ import threading
import time import time
import webbrowser import webbrowser
import winreg import winreg
import tempfile
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from proxy.utils import build_github_opener
try: try:
import pyperclip import pyperclip
@@ -219,9 +222,6 @@ def update_ctk_form(
def _perform_update(download_url: str, set_status=None) -> None: def _perform_update(download_url: str, set_status=None) -> None:
import tempfile
import urllib.request
def _step(msg: str) -> None: def _step(msg: str) -> None:
log.info("Update: %s", msg) log.info("Update: %s", msg)
if set_status: if set_status:
@@ -244,7 +244,14 @@ def _perform_update(download_url: str, set_status=None) -> None:
os.close(fd) os.close(fd)
tmp_path = Path(tmp_name) tmp_path = Path(tmp_name)
log.info("Downloading update from %s", download_url) log.info("Downloading update from %s", download_url)
urllib.request.urlretrieve(download_url, str(tmp_path)) opener = build_github_opener()
with opener.open(download_url) as _resp:
with open(str(tmp_path), "wb") as _fout:
while True:
_chunk = _resp.read(65536)
if not _chunk:
break
_fout.write(_chunk)
except Exception as exc: except Exception as exc:
_err(f"Не удалось скачать:\n{exc}") _err(f"Не удалось скачать:\n{exc}")
if tmp_path: if tmp_path: