Déploiement Furtif de MTProxy via Nginx sur le Port 443 pour Telegram
Cet article aborde un défi crucial pour les administrateurs système et les développeurs : déployer MTProxy de Telegram sur le port HTTPS standard 443 sans perturber les services web existants gérés par Nginx. Cette configuration améliore considérablement la résilience du proxy face à la détection et au blocage, en déguisant son trafic en trafic web ordinaire. La principale complexité réside dans la capacité de Nginx à acheminer correctement les requêtes, en distinguant les sites HTTP/HTTPS cibles de MTProxy tout en utilisant le même port. Ce guide détaille le mécanisme de fonctionnement du module stream de Nginx et son intégration avec mtprotoproxy pour créer une solution robuste et discrète.
Comment Nginx Stream fonctionne pour le multiplexage
Pour que MTProxy et Nginx coexistent avec succès sur le port 443, un mécanisme de routage intelligent est essentiel. Le module stream de Nginx, opérant au niveau de la couche TCP/UDP, permet l'analyse des données de connexion initiales avant le traitement complet de la couche application. Un aspect clé est que le champ Server Name Indication (SNI) dans un message TLS ClientHello est transmis en texte clair, même pour les connexions chiffrées. Cela permet à Nginx de lire le nom d'hôte demandé sans déchiffrer l'intégralité du flux SSL.
La solution proposée utilise la logique suivante :
- Réaffectation des ports pour les hôtes HTTPS : Tous les hôtes virtuels HTTPS Nginx existants qui écoutaient auparavant sur le port 443 sont déplacés vers un port interne, tel que 4443. Cela libère le port 443 pour un gestionnaire centralisé.
- Nginx Stream comme routeur central : Un serveur
streamNginx est configuré sur le port 443 désormais disponible. Ce serveur utilise la directivessl_preread onpour extraire le SNI des connexions SSL entrantes. - Routage dynamique : En fonction du SNI extrait, Nginx
streamprend une décision :
* Si le SNI correspond au nom de domaine choisi pour MTProxy (par exemple, myprovider.ru), la connexion est transmise à MTProxy (qui écoutera sur un port local, tel que 7788).
* Si le SNI correspond à tout autre nom de domaine, la connexion est redirigée vers Nginx, mais vers le port interne 4443, où elle sera traitée par les hôtes virtuels HTTPS standards.
- Préservation de l'IP réelle : Pour une journalisation précise, une analyse du trafic et un bon fonctionnement des applications derrière Nginx,
proxy_protocolest utilisé. Cela permet de transmettre l'adresse IP réelle du client le long de la chaîne de proxy.
Cette approche permet à MTProxy de se faire passer pour du trafic HTTPS ordinaire, en utilisant le même port que le serveur web. Cela renforce considérablement sa résilience face à la détection et au blocage, rendant son trafic indiscernable des connexions web standards.
Configuration de Nginx pour la coexistence
La première étape consiste à modifier la configuration de tous les hôtes virtuels HTTPS Nginx existants. Vous devez changer le port sur lequel ils écoutent, de 443 à un port interne, par exemple, 127.0.0.1:4443. Cela garantit que Nginx traitera ces requêtes après que le module stream les ait redirigées.
Exemple de modification du bloc server :
server {
server_name mywebsite.ru;
listen 127.0.0.1:4443 ssl http2 proxy_protocol;
set_real_ip_from 127.0.0.1; # Trust localhost as the PROXY Protocol source
real_ip_header proxy_protocol; # Extract IP from PROXY Protocol header
real_ip_recursive on; # Apply recursively for correct IP determination
# ... other directives for your server block ...
ssl_certificate /etc/letsencrypt/live/mywebsite.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.ru/privkey.pem;
# ... other SSL/TLS settings ...
}
La directive proxy_protocol dans listen indique à Nginx d'attendre un en-tête PROXY Protocol. set_real_ip_from et real_ip_header sont cruciaux pour que Nginx identifie et transmette correctement l'adresse IP réelle du client, plutôt que l'IP de l'hôte local (127.0.0.1) qui sera utilisée par Nginx Stream. Sans ces paramètres, toutes les requêtes vers vos sites sembleraient provenir de 127.0.0.1, ce qui pourrait perturber la fonctionnalité des applications, la journalisation et les systèmes de sécurité.
L'étape suivante consiste à créer un nouveau fichier de configuration pour le module stream de Nginx. Il est recommandé de le placer dans /etc/nginx/conf.d/stream.conf ou un autre emplacement approprié qui garantit son chargement par Nginx.
stream {
log_format stream '$remote_addr [$time_local] host=$ssl_preread_server_name '
'prot=$protocol status=$status out=$bytes_sent in=$bytes_received';
# Optional: enable logging for debugging
#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; # Traffic for the selected MTProxy domain
default nginx_https; # All other HTTPS traffic
}
upstream nginx_https {
server 127.0.0.1:4443; # Redirect to Nginx's internal port
}
upstream tg_proxy {
server 127.0.0.1:7788; # Redirect to MTProxy's local port
}
server {
listen 443 reuseport; # Listen on the main 443 port
proxy_pass $backend_name;
ssl_preread on; # Enable SNI reading to determine hostname
proxy_protocol on; # Enable PROXY Protocol to pass the real IP
}
}
Dans ce bloc, map est utilisé pour associer le SNI ($ssl_preread_server_name) à un nom de backend. $backend_name sera soit tg_proxy, soit nginx_https selon le domaine demandé. La directive upstream définit où le trafic sera transféré pour chaque backend. listen 443 reuseport permet à plusieurs processus Nginx d'écouter sur le même port, améliorant les performances et la tolérance aux pannes. ssl_preread on est une directive cruciale qui permet à Nginx d'obtenir le SNI sans déchiffrer l'intégralité du trafic SSL.
Si votre installation Nginx actuelle ne prend pas en charge le module stream (par exemple, il s'agit d'une version minimale), vous devrez l'installer. Sur Debian/Ubuntu, cela se fait avec la commande :
sudo apt install nginx-full
Après avoir effectué toutes les modifications, vous devez vérifier la configuration Nginx et la redémarrer :
nginx -t && sudo systemctl restart nginx
L'utilisation de systemctl restart au lieu de service nginx restart est l'approche plus moderne et préférée sur les systèmes basés sur systemd.
Installation et configuration de MTProxy
Pour implémenter MTProxy dans cette configuration, nous utiliserons l'implémentation Python très efficace mtprotoproxy d'alexbers, qui s'intègre bien avec proxy_protocol de Nginx et prend en charge le mode de masquage TLS requis.
Le processus d'installation implique le clonage du dépôt et le passage à la branche appropriée :
(cd /opt || sudo mkdir /opt && sudo chown $(whoami):$(whoami) /opt) && cd /opt
git clone https://github.com/alexbers/mtprotoproxy.git
cd mtprotoproxy
# Important: At the time of writing, stable operation with this configuration is achieved on the master branch
git checkout master
Ensuite, générez un secret pour MTProxy. Ce secret sera utilisé par les clients Telegram pour l'authentification et doit être unique :
head -c 16 /dev/urandom | xxd -ps
La valeur hexadécimale de 32 caractères résultante doit être sauvegardée. Maintenant, vous devez créer ou modifier le fichier config.py dans le répertoire mtprotoproxy :
# /opt/mtprotoproxy/config.py
PORT = 7788 # Local port to which Nginx Stream will redirect traffic
LISTEN_ADDR_IPV4 = "127.0.0.1" # Bind to localhost for security
LISTEN_ADDR_IPV6 = None # Disable IPv6 if not needed or configured
# Dictionary of users and their secrets. Multiple can be created for different groups.
USERS = {
"tg_user_1": "YOUR_GENERATED_SECRET_HERE",
# "tg_user_2": "0123456789abcdef0123456789abcdef", # Example of an additional secret
}
# MTProxy operating modes
MODES = {
"classic": False, # Classic mode, easily detectable
"secure": False, # Improved mode, but not optimal for masquerading
"tls": True # TLS masquerading mode, most resistant to detection
}
# Domain for TLS mode. MTProxy will check its availability on startup.
# Use the domain you selected in the Nginx Stream configuration.
TLS_DOMAIN = "myprovider.ru" # Domain that will be used for MTProxy
PROXY_PROTOCOL = True # Mandatory setting for working with Nginx Stream
# AD_TAG = "GET_YOUR_AD_TAG_FROM_@MTProxybot" # Optional: for advertising tag
Les paramètres clés ici incluent : LISTEN_ADDR_IPV4 = "127.0.0.1" garantit que MTProxy n'est accessible que via Nginx sur le même serveur, améliorant la sécurité. MODES = {"tls": True} active le mode de masquage TLS, rendant le trafic MTProxy indiscernable du HTTPS ordinaire. TLS_DOMAIN doit correspondre au nom de domaine spécifié dans la directive map de Nginx Stream pour que Nginx identifie et transmette correctement le trafic. Enfin, PROXY_PROTOCOL = True permet à MTProxy de recevoir l'adresse IP réelle du client de Nginx, ce qui est crucial pour un fonctionnement et une journalisation corrects.
Vérification et démarrage automatisé
Après avoir configuré Nginx et MTProxy, il est essentiel de vérifier minutieusement le bon fonctionnement de l'ensemble du système.
Vérification du fonctionnement de MTProxy et Nginx
- Démarrage manuel de MTProxy : Naviguez vers le répertoire
/opt/mtprotoproxyet démarrez manuellement MTProxy pour une vérification initiale :
```bash
python3 mtprotoproxy.py
```
Une ligne avec les paramètres de connexion du proxy devrait apparaître dans la console, par exemple :
```
tg_user_1: tg://proxy?server=YOUR_VM_IP&port=7788&secret=LONG_SECRET
```
Note importante : Le secret affiché ici aura un préfixe ee et contiendra le TLS_DOMAIN encodé spécifié dans config.py. Cela fait partie du mécanisme de masquage TLS. Copiez ce lien.
- Test avec un client Telegram :
* Dans le lien copié, changez le port de 7788 à 443.
* Envoyez le lien résultant à vos "Messages enregistrés" dans Telegram.
* Cliquez sur le lien et sélectionnez "Connecter".
* Si tout est configuré correctement, Telegram devrait se connecter avec succès via le proxy. Pour une vérification supplémentaire, vous pouvez envoyer la commande /ping à n'importe quel bot (par exemple, @MTProxybot) — un message avec le ping actuel du proxy devrait être renvoyé.
- Vérification du masquage HTTPS : Pour confirmer que MTProxy se fait correctement passer pour un site web ordinaire, effectuez la vérification suivante :
* Ajoutez la ligne suivante à votre fichier hosts local (pour Linux/macOS, c'est /etc/hosts ; pour Windows, c'est %SystemRoot%\System32\drivers\etc\hosts) :
```
YOUR_VM_IP myprovider.ru
```
* Remplacez YOUR_VM_IP par l'adresse IP réelle de votre serveur.
* Ouvrez https://myprovider.ru dans votre navigateur.
* Si tout fonctionne correctement, vous devriez voir le contenu de myprovider.ru (le site web de votre fournisseur ou tout autre domaine que vous avez spécifié dans TLS_DOMAIN). Cela confirme que Nginx Stream a redirigé la requête vers MTProxy, et que MTProxy, la reconnaissant comme du trafic non-Telegram, l'a transparentement proxifiée vers la ressource web originale, démontrant un masquage TLS réussi.
* N'oubliez pas de supprimer la ligne ajoutée de votre fichier hosts après vérification.
Configuration de MTProxy en tant que service Systemd
Pour garantir que MTProxy démarre automatiquement au démarrage du système et fonctionne en continu, il est recommandé de le configurer en tant que service systemd.
- Arrêtez le MTProxy exécuté manuellement (
Ctrl+C). - Créez un fichier d'unité
systemdà l'emplacement/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
```
Ici, User=nobody et Group=nogroup améliorent la sécurité en exécutant le service avec des privilèges minimaux. WorkingDirectory pointe vers le répertoire où se trouve le script mtprotoproxy.py.
- Rechargez la configuration
systemd, activez le service et démarrez-le :
```bash
sudo systemctl daemon-reload
sudo systemctl enable mtprotoproxy.service
sudo systemctl start mtprotoproxy.service
```
- Vérifiez l'état du service :
```bash
systemctl status mtprotoproxy.service
```
La sortie devrait indiquer que le service est active (running).
- Consulter les journaux : Pour le débogage ou la surveillance, utilisez :
```bash
journalctl -u mtprotoproxy.service -e
```
Cette configuration complète vous permet d'utiliser MTProxy de Telegram sur le port 443, en le masquant efficacement comme du trafic HTTPS ordinaire, tout en préservant toutes les fonctionnalités des sites web existants sur le même serveur.
Points Clés :
- L'utilisation de
ssl_prereaddans Nginx Stream permet le routage du trafic basé sur le SNI sans déchiffrement, ce qui est essentiel pour séparer le trafic MTProxy et HTTPS sur un seul port. - La configuration de
proxy_protocolà la fois dans Nginx et MTProxy assure la transmission de l'adresse IP réelle du client, ce qui est vital pour la journalisation et la sécurité. - MTProxy est configuré en mode
tls: TrueavecTLS_DOMAINspécifié, rendant le trafic du proxy indiscernable d'une connexion HTTPS régulière vers ce domaine. - Lier MTProxy à
127.0.0.1renforce la sécurité en restreignant l'accès externe direct. - Le service
systemdassure le démarrage automatique et la surveillance de MTProxy, garantissant son fonctionnement continu.
— Editorial Team
Aucun commentaire pour le moment.