MTProxy na porcie 443 z Nginx: Ukryta konfiguracja dla Telegrama
Artykuł poświęcony jest aktualnemu wyzwaniu dla administratorów systemów i deweloperów: wdrożeniu Telegram MTProxy na standardowym porcie HTTPS 443, bez zakłócania pracy istniejących usług webowych zarządzanych przez Nginx. Taka konfiguracja znacząco zwiększa odporność proxy na wykrycie i blokowanie, maskując jego ruch jako zwykły ruch webowy. Główna trudność polega na tym, że Nginx musi poprawnie kierować zapytania, rozróżniając docelowe strony HTTP/HTTPS i MTProxy, jednocześnie używając tego samego portu. Ten przewodnik szczegółowo opisuje mechanizm działania modułu stream Nginx i jego integrację z mtprotoproxy w celu stworzenia niezawodnego i dyskretnego rozwiązania.
Mechanizm działania Nginx Stream dla multipleksowania
Aby MTProxy i Nginx mogły współistnieć na porcie 443, potrzebny jest inteligentny mechanizm routingu. Moduł stream Nginx, działający na poziomie TCP/UDP, pozwala analizować początkowe dane połączenia przed pełnym przetworzeniem na poziomie aplikacji. Kluczowym aspektem jest to, że pole Server Name Indication (SNI) w wiadomości TLS ClientHello jest przesyłane w otwartym tekście, nawet dla zaszyfrowanych połączeń. Dzięki temu Nginx może odczytać żądaną nazwę hosta bez deszyfrowania całego strumienia SSL.
Proponowane rozwiązanie wykorzystuje następującą logikę:
- Przekierowanie portów dla hostów HTTPS: Wszystkie istniejące wirtualne hosty HTTPS Nginx, które wcześniej nasłuchiwały na porcie 443, są przenoszone na wewnętrzny port, np. 4443. To zwalnia port 443 dla scentralizowanego obsługiwania.
- Nginx Stream jako centralny router: Na zwolnionym porcie 443 konfigurowany jest serwer
streamNginx. Ten serwer używa dyrektywyssl_preread ondo wyodrębniania SNI z przychodzących połączeń SSL. - Dynamiczne routowanie: Na podstawie otrzymanego SNI, Nginx
streampodejmuje decyzję:
* Jeśli SNI odpowiada wybranej nazwie domeny dla MTProxy (np. myprovider.ru), połączenie jest przekierowywane do MTProxy (który będzie nasłuchiwał na lokalnym porcie, np. 7788).
* Jeśli SNI odpowiada jakiejkolwiek innej nazwie domeny, połączenie jest przekierowywane z powrotem do Nginx, ale już na wewnętrzny port 4443, gdzie zostanie przetworzone przez standardowe wirtualne hosty HTTPS.
- Zachowanie rzeczywistego IP: Dla poprawnego działania logowania i analizy ruchu, a także dla prawidłowego działania aplikacji za Nginx, używany jest
proxy_protocol. Pozwala to na przekazywanie rzeczywistego adresu IP klienta w łańcuchu proxy.
Takie podejście pozwala MTProxy maskować się pod zwykły ruch HTTPS, używając tego samego portu co serwer webowy, co znacząco zwiększa jego odporność na wykrycie i blokowanie, czyniąc jego ruch nierozróżnialnym od standardowych połączeń webowych.
Konfiguracja Nginx dla trybu współistnienia
Pierwszym krokiem jest modyfikacja konfiguracji wszystkich istniejących wirtualnych hostów HTTPS Nginx. Należy zmienić port, na którym nasłuchują, z 443 na wewnętrzny, np. 127.0.0.1:4443. Gwarantuje to, że Nginx będzie przetwarzał te zapytania po tym, jak moduł stream je przekieruje.
Przykład zmiany konfiguracji bloku server:
server {
server_name mywebsite.ru;
listen 127.0.0.1:4443 ssl http2 proxy_protocol;
set_real_ip_from 127.0.0.1; # Ufamy localhost jako źródłu PROXY Protocol
real_ip_header proxy_protocol; # Wyodrębniamy IP z nagłówka PROXY Protocol
real_ip_recursive on; # Stosujemy rekurencyjnie dla poprawnego określenia IP
# ... pozostałe dyrektywy bloku server ...
ssl_certificate /etc/letsencrypt/live/mywebsite.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.ru/privkey.pem;
# ... inne ustawienia SSL/TLS ...
}
Dyrektywa proxy_protocol w listen instruuje Nginx, aby oczekiwał nagłówka PROXY Protocol. set_real_ip_from i real_ip_header są krytyczne dla tego, aby Nginx poprawnie identyfikował i przekazywał rzeczywisty adres IP klienta, a nie adres IP lokalnego hosta (127.0.0.1), który będzie używany przez Nginx Stream. Bez tych ustawień wszystkie zapytania do Twoich stron będą wyglądać tak, jakby pochodziły z 127.0.0.1, co może zakłócić działanie aplikacji, logowanie i systemy bezpieczeństwa.
Następnym krokiem jest stworzenie nowego pliku konfiguracyjnego dla modułu stream Nginx. Zaleca się umieszczenie go w /etc/nginx/conf.d/stream.conf lub w innym odpowiednim miejscu, które zapewni jego załadowanie przez Nginx.
stream {
log_format stream '$remote_addr [$time_local] host=$ssl_preread_server_name '
'prot=$protocol status=$status out=$bytes_sent in=$bytes_received';
# Opcjonalnie: włącz logowanie do debugowania
#access_log /var/log/nginx/stream_access.log stream;
#error_log /var/log/nginx/stream_error.log;
map $ssl_preread_server_name $backend_name {
myprovider.ru tg_proxy; # Ruch dla wybranej domeny MTProxy
default nginx_https; # Cały pozostały ruch HTTPS
}
upstream nginx_https {
server 127.0.0.1:4443; # Przekierowujemy na wewnętrzny port Nginx
}
upstream tg_proxy {
server 127.0.0.1:7788; # Przekierowujemy na lokalny port MTProxy
}
server {
listen 443 reuseport; # Nasłuchujemy na głównym porcie 443
proxy_pass $backend_name;
ssl_preread on; # Włączamy odczyt SNI do określenia nazwy hosta
proxy_protocol on; # Włączamy PROXY Protocol do przekazywania rzeczywistego IP
}
}
W tym bloku map jest używany do mapowania SNI ($ssl_preread_server_name) na nazwę backendu. $backend_name będzie albo tg_proxy, albo nginx_https w zależności od żądanej domeny. Dyrektywa upstream określa, dokąd dokładnie zostanie przekierowany ruch dla każdego backendu. listen 443 reuseport pozwala wielu procesom Nginx nasłuchiwać na tym samym porcie, co zwiększa wydajność i odporność na awarie. ssl_preread on jest kluczową dyrektywą, pozwalającą Nginx uzyskać SNI bez deszyfrowania całego ruchu SSL.
Jeśli Twój obecny Nginx nie obsługuje modułu stream (np. jest to minimalna kompilacja), należy go zainstalować. Dla Debian/Ubuntu odbywa się to za pomocą polecenia:
sudo apt install nginx-full
Po wprowadzeniu wszystkich zmian należy sprawdzić konfigurację Nginx i ponownie go uruchomić:
nginx -t && sudo systemctl restart nginx
Użycie systemctl restart zamiast service nginx restart jest bardziej nowoczesnym i preferowanym podejściem w systemach opartych na systemd.
Instalacja i Konfiguracja MTProxy
Do implementacji MTProxy w tym schemacie zostanie użyta wysoce wydajna implementacja Python mtprotoproxy od alexbers, która dobrze integruje się z Nginx proxy_protocol i obsługuje niezbędny tryb maskowania TLS.
Proces instalacji obejmuje klonowanie repozytorium i przejście na aktualną gałąź:
(cd /opt || sudo mkdir /opt && sudo chown $(whoami):$(whoami) /opt) && cd /opt
git clone https://github.com/alexbers/mtprotoproxy.git
cd mtprotoproxy
# Ważne: w momencie pisania artykułu stabilna praca z tą konfiguracją jest osiągana na gałęzi master
git checkout master
Następnie należy wygenerować sekret dla MTProxy. Ten sekret będzie używany przez klientów Telegrama do uwierzytelniania i musi być unikalny:
head -c 16 /dev/urandom | xxd -ps
Uzyskaną 32-znakową wartość szesnastkową należy zapisać. Teraz należy utworzyć lub edytować plik config.py w katalogu mtprotoproxy:
# /opt/mtprotoproxy/config.py
PORT = 7788 # Lokalny port, na który Nginx Stream będzie przekierowywał ruch
LISTEN_ADDR_IPV4 = "127.0.0.1" # Powiązanie z localhost dla bezpieczeństwa
LISTEN_ADDR_IPV6 = None # Wyłącz IPv6, jeśli nie jest wymagane lub skonfigurowane
# Słownik użytkowników i ich sekretów. Można stworzyć kilka dla różnych grup.
USERS = {
"tg_user_1": "TWÓJ_WYGENEROWANY_SEKRET_TUTAJ",
# "tg_user_2": "0123456789abcdef0123456789abcdef", # Przykład dodatkowego sekretu
}
# Tryby pracy MTProxy
MODES = {
"classic": False, # Tryb klasyczny, łatwo wykrywalny
"secure": False, # Tryb ulepszony, ale nie optymalny do maskowania
"tls": True # Tryb maskowania TLS, najbardziej odporny na wykrycie
}
# Domena dla trybu TLS. MTProxy sprawdzi jej dostępność przy starcie.
# Użyj domeny, którą wybrałeś w konfiguracji Nginx Stream.
TLS_DOMAIN = "myprovider.ru" # Domena, która będzie używana dla MTProxy
PROXY_PROTOCOL = True # Obowiązkowe ustawienie do pracy z Nginx Stream
# AD_TAG = "UZYSKAJ_SWÓJ_AD_TAG_OD_@MTProxybot" # Opcjonalnie: dla tagu reklamowego
Kluczowe ustawienia tutaj: LISTEN_ADDR_IPV4 = "127.0.0.1" zapewnia, że MTProxy będzie dostępny tylko poprzez Nginx na tym samym serwerze, zwiększając bezpieczeństwo. MODES = {"tls": True} aktywuje tryb maskowania TLS, który sprawia, że ruch MTProxy jest nierozróżnialny od zwykłego HTTPS. TLS_DOMAIN musi zgadzać się z nazwą domeny podaną w dyrektywie map Nginx Stream, aby Nginx mógł poprawnie identyfikować i przekierowywać ruch. Wreszcie, PROXY_PROTOCOL = True pozwala MTProxy otrzymywać rzeczywisty adres IP klienta od Nginx, co jest ważne dla poprawnego działania i logowania.
Weryfikacja i Automatyzacja Uruchamiania
Po skonfigurowaniu Nginx i MTProxy należy dokładnie sprawdzić działanie całego systemu.
Sprawdzenie funkcjonowania MTProxy i Nginx
- Ręczne uruchomienie MTProxy: Przejdź do katalogu
/opt/mtprotoproxyi uruchom MTProxy ręcznie w celu wstępnej weryfikacji:
```bash
python3 mtprotoproxy.py
```
W konsoli powinien pojawić się wiersz z parametrami do połączenia z proxy, na przykład:
```
tg_user_1: tg://proxy?server=IP_TWOJEJ_MASZYNY_WIRTUALNEJ&port=7788&secret=DŁUGI_SEKRET
```
Ważna uwaga: Sekret wyświetlony tutaj będzie miał prefiks ee i będzie zawierał zakodowaną nazwę domeny TLS_DOMAIN, określoną w config.py. Jest to część mechanizmu maskowania TLS. Skopiuj ten link.
- Testowanie klientem Telegrama:
* W skopiowanym linku zmień port z 7788 na 443.
* Wyślij uzyskany link do siebie w "Zapisanych wiadomościach" w Telegramie.
* Kliknij link i wybierz "Połącz".
* Jeśli wszystko jest poprawnie skonfigurowane, Telegram powinien pomyślnie połączyć się przez proxy. Dla dodatkowej weryfikacji możesz wysłać komendę /ping do dowolnego bota (np. @MTProxybot) — w odpowiedzi powinieneś otrzymać wiadomość z aktualnym pingiem proxy.
- Sprawdzenie maskowania pod HTTPS: Aby upewnić się, że MTProxy poprawnie maskuje się pod zwykłą stronę internetową, należy wykonać następującą weryfikację:
* Dodaj do swojego lokalnego pliku hosts (dla Linux/macOS to /etc/hosts, dla Windows — %SystemRoot%\System32\drivers\etc\hosts) wiersz:
```
IP_TWOJEJ_MASZYNY_WIRTUALNEJ myprovider.ru
```
Zastąp IP_TWOJEJ_MASZYNY_WIRTUALNEJ rzeczywistym adresem IP Twojego serwera.
* Otwórz w przeglądarce https://myprovider.ru.
* Jeśli wszystko działa poprawnie, powinieneś zobaczyć zawartość strony myprovider.ru (strony Twojego dostawcy lub innej domeny, którą wskazałeś w TLS_DOMAIN). Potwierdza to, że Nginx Stream przekierował zapytanie do MTProxy, a MTProxy, rozpoznając je jako ruch nie-Telegramowy, transparentnie przekierował je do oryginalnego zasobu webowego, demonstrując udane maskowanie TLS.
* Nie zapomnij usunąć dodanego wiersza z pliku hosts po weryfikacji.
Konfiguracja MTProxy jako usługi systemowej (Systemd)
Aby zapewnić automatyczne uruchamianie MTProxy przy starcie systemu i jego ciągłą pracę, zaleca się skonfigurowanie go jako usługi systemd.
- Zatrzymaj ręcznie uruchomiony MTProxy (
Ctrl+C). - Utwórz plik jednostki
systemdpod ścieżką/etc/systemd/system/mtprotoproxy.service:
```ini
[Unit]
Description=MTProto Proxy
After=network.target
[Service]
Type=simple
User=nobody
Group=nogroup
WorkingDirectory=/opt/mtprotoproxy
ExecStart=/usr/bin/python3 /opt/mtprotoproxy/mtprotoproxy.py
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
```
Tutaj User=nobody i Group=nogroup zwiększają bezpieczeństwo, uruchamiając usługę z minimalnymi uprawnieniami. WorkingDirectory wskazuje na katalog, w którym znajduje się skrypt mtprotoproxy.py.
- Przeładuj konfigurację
systemd, włącz usługę i uruchom ją:
```bash
sudo systemctl daemon-reload
sudo systemctl enable mtprotoproxy.service
sudo systemctl start mtprotoproxy.service
```
- Sprawdź status usługi:
```bash
systemctl status mtprotoproxy.service
```
W wyniku powinno być wskazane, że usługa jest active (running).
- Przeglądanie logów: Do debugowania lub monitorowania użyj:
```bash
journalctl -u mtprotoproxy.service -e
```
Ta kompleksowa konfiguracja pozwala na używanie Telegram MTProxy na porcie 443, skutecznie maskując go pod zwykły ruch HTTPS, jednocześnie zachowując pełną funkcjonalność istniejących stron internetowych na tym samym serwerze.
Co ważne:
- Użycie
ssl_prereadw Nginx Stream pozwala na routowanie ruchu na podstawie SNI bez deszyfrowania, co jest kluczowe dla rozdzielenia MTProxy i ruchu HTTPS na jednym porcie. - Konfiguracja
proxy_protocolw Nginx i MTProxy zapewnia przekazywanie rzeczywistego adresu IP klienta, co jest ważne dla logowania i bezpieczeństwa. - MTProxy jest konfigurowany w trybie
tls: Truez podaniemTLS_DOMAIN, aby ruch proxy był nierozróżnialny od zwykłego połączenia HTTPS z tą domeną. - Powiązanie MTProxy z
127.0.0.1zwiększa bezpieczeństwo, ograniczając bezpośredni dostęp z zewnątrz. - Usługa systemowa
systemdgwarantuje automatyczne uruchamianie i monitorowanie MTProxy, zapewniając jego ciągłą pracę.
— Editorial Team
Brak komentarzy.