XTLS-Reality, XHTTP, Naiveproxy e AnyTLS são apenas a ponta do iceberg. Vamos explorar onde o verdadeiro "insanity" se esconde no mundo dos proxies e VPNs, especialmente em tempos onde até as ideias mais bizarras podem se tornar ferramentas úteis para manter a sanidade.
Pingtunnel A ideia por trás do Pingtunnel é tão clássica quanto um sanduíche: pacotes ICMP podem carregar dados úteis. Não apenas para verificar a conectividade, mas para transportar um fluxo de bytes do cliente para o servidor. Se isso é possível, nada impede que seja usado para proxy.
A implementação mais conhecida é o Pingtunnel. Configurar o servidor é ridiculamente simples: desative as respostas automáticas de ping no sysctl para evitar interferências, coloque o binário em um VPS e execute-o com a flag -server:
bash./pingtunnel -type server
Opcionalmente, você pode adicionar a flag -key com um número entre 0 e 2147483647. Isso não é criptografia completa (a criptografia é feita pelo software cliente via TLS), mas sim uma proteção rudimentar contra olhares curiosos, fazendo os pacotes parecerem um conjunto aleatório de bytes.
No lado do cliente, o mesmo binário é usado com parâmetros de cliente:
bashpingtunnel -type client -l :4455 -s www.yourserver.com -sock5 1
Isso abre um proxy SOCKS na porta 4455. Para Windows, Linux e, surpreendentemente, Android, existe um cliente gráfico chamado itismoej/pingtunnel-client. Basta adicionar uma nova conexão com um URL no formato pingtunnel://your-server-ip?key=XXX&mode=vpn, conectar e pronto.
No Windows, pode haver um bug em um bundle mal compilado que causa um erro "Unable to load asset" ao tentar iniciar uma conexão. A solução é criar a pasta assets/binaries/pingtunnel/windows-amd64, colocar o pingtunnel.exe dentro e definir a variável de ambiente PINGTUNNEL_ASSETS_DIR para o caminho raiz dessa pasta (onde a pasta assets reside).
Esteja ciente de que muitos antivírus detectam o Pingtunnel como HackTool, possivelmente porque malware o utilizou como transporte. O funcionamento do Pingtunnel varia: em redes com listas brancas de ICMP, ele pode não funcionar, mas em outros lugares, funciona perfeitamente. Alguns provedores de hospedagem podem acionar firewalls, interpretando um grande volume de pacotes ICMP de um único endereço como um ataque DDoS. No entanto, na maioria dos casos, ele funciona muito bem!
Importante: Existe outro cliente PingTunnel para Android no Google Play e no GitHub da HexaSoftware (que aparece nas primeiras posições das buscas). Não o recomendo, pois funciona mal, às vezes não conecta ou é extremamente lento, tornando a navegação impossível. É melhor usar o cliente cuja link foi fornecido anteriormente.
A propósito, o XRay agora possui um transporte similar chamado XICMP, embora a implementação ainda esteja crua e, como de costume, com pouca documentação. E onde mais encontramos um túnel ICMP? No jogo War Thunder, dentro do GoST, um excelente comboio sobre o qual falamos neste artigo: GOST: o canivete suíço para tunelamento e evasão de bloqueios / Habr.
DNSTT, Slipstream, MasterDnsVpn
Aqui, a ideia é diferente: usar DNS para proxy. É crucial entender que não se trata apenas de encapsular seus dados em pacotes DNS e enviá-los para seu servidor. Não, não. Estes métodos utilizam servidores DNS públicos (como o do seu provedor). O cliente faz uma consulta DNS para um domínio como qJdESz0gPBiqojX1jK6kOLn1FAlnEuF9enklEWHlPpQ.yourdomain.com. O servidor DNS do seu provedor, sem saber o que é esse domínio, pergunta ao ns.yourdomain.com (que você controla) "Ei, irmão, me diga - o que é esse subdomínio aí?". Ele responde: este domínio tem um registro TXT com o valor "alWXjPTjL0LwKN-Q3gtd25fkVN73UwPk2XEupyG6Rgc" (onde a informação transmitida também está codificada), e o servidor DNS do seu provedor repassa esse conhecimento de volta ao cliente. Dessa forma, os dados são trocados usando apenas o DNS do provedor (ou outro).
Naturalmente, uma implementação ingênua é muito lenta e não confiável. Por isso, pessoas inteligentes começaram a pensar em otimizações.
O método mais antigo e conhecido é o DNSTT, que utiliza algoritmos do protocolo KCP. No Habr, existe um excelente artigo sobre sua configuração: DNSTT. Túnel DNS para contornar bloqueios / Habr. No XRay, aparentemente, uma implementação muito semelhante surgiu recentemente sob o nome XDNS, mas não a verifiquei - faltou tempo, e o DNSTT em si já é coisa do passado.
Agora, para opções mais modernas. Apresentamos: SlipStream. Quase a mesma coisa, mas utiliza os mecanismos do protocolo QUIC e, sim, funciona muito mais rápido.
A implementação original: EndPositive/slipstream: High-performance multi-path covert channel over DNS é bastante instável e cheia de bugs, mas existe uma reescrita em Rust: Mygod/slipstream-rust: High-performance multi-path covert channel over DNS in Rust with vibe coding - e ela funciona muito bem.
Dos clientes móveis, experimentei o DNSTT.XYZ (apesar do nome, ele suporta SlipStream) e o SlipNet Lite (sua licença não é permissiva, mas é muito bom).
Existem outros clientes de qualidade variada, como um plugin para Shadowsocks: Mygod/slipstream-plugin-android: SIP003 Android plugin using slipstream-rust.
E agora, a artilharia pesada - MasterDnsVPN. Como diz o autor, "Seu objetivo principal é semelhante a projetos como DNSTT ou SlipStream, mas tem uma estrutura e abordagem de implementação fundamentalmente diferentes. Este sistema foi projetado para ser compatível com muitos tipos de comportamento de resolvedores e condições de rede complexas, com o objetivo de manter a maior estabilidade e entrega de dados possível, mesmo nos piores cenários."
E ele realmente conseguiu. Entre todos os protocolos que testei, este é o mais rápido e estável, e em comparação com o DNSTT original, é como comparar o céu e a terra. Além disso, há uma enorme quantidade de parâmetros que podem ser ajustados para otimização fina.
O cliente de console funciona em qualquer lugar e em qualquer sistema, e existem dois bons clientes para Android: Hidden-Node/MasterDnsVPN-AndroidClient: MasterDnsVPN Android client (community build) based on the upstream Go core—install signed APKs from Releases and connect to your own MasterDnsVPN server (domain/key/resolvers). e RevocGG/MasterDnsVPN-AndroidGG: MasterDnsVPN Android Client (o segundo me agrada mais, o primeiro parece ter sido feito de forma descuidada).
A principal questão é quais DNS usar. Alguns DNS públicos podem se tornar inacessíveis em certas condições. Alguns servidores DNS podem ter limites de taxa (ratelimit), resultando em, por exemplo, que através de um túnel assim você ainda consiga se comunicar no Telegram e navegar lentamente, mas não poderá assistir a vídeos. E também pode acontecer que o provedor intercepte todas as consultas não criptografadas na porta UDP 53 e as redirecione para seus próprios servidores (mas nem todos fazem isso).
Portanto, o procedimento é o seguinte: primeiro, tente os DNS do provedor (nem todos os clientes conseguem pegá-los automaticamente, vale a pena verificar nas configurações de conexão e inseri-los manualmente), depois tente os públicos como 8.8.8.8 e 1.1.1.1 (talvez estejam disponíveis?), há também o servidor DNS da MSK-IX 62.76.76.62, e o cúmulo do cinismo - o servidor do Roskomnadzor (NSDI) 195.208.4.1 :)
Se nada do acima funcionar, vá para um destes locais: DNS servers in Russian Federation, baixe a lista como um arquivo de texto, insira no cliente e deixe-o verificar. E para não ter que verificar muitos, você pode usar um script simples em Python que, para começar, filtrará as opções definitivamente inacessíveis:
Script aqui:
python#!/usr/bin/env python3 """ Usage: ./resolve_check.py <ip_list_file> <domain> <output_file> [--timeout 3] [--workers 50] """ import argparse import ipaddress import sys from concurrent.futures import ThreadPoolExecutor, as_completed import dns.resolver import dns.exception def load_ipv4_addresses(path: str) -> list[str]: """Read file, return unique IPv4 addresses preserving order.""" seen = set() ips = [] with open(path, "r", encoding="utf-8") as f: for line_no, raw in enumerate(f, 1): line = raw.strip() if not line or line.startswith("#"): continue try: addr = ipaddress.ip_address(line) except ValueError: print(f"[skip] line {line_no}: not an IP -> {line}", file=sys.stderr) continue if not isinstance(addr, ipaddress.IPv4Address): continue # ignore IPv6 s = str(addr) if s not in seen: seen.add(s) ips.append(s) return ips def can_resolve(ip: str, domain: str, timeout: float) -> bool: """Return True if `ip` (used as DNS server) successfully resolves `domain`.""" resolver = dns.resolver.Resolver(configure=False) resolver.nameservers = [ip] resolver.timeout = timeout # per-try resolver.lifetime = timeout # total try: answer = resolver.resolve(domain, "A") return len(answer) > 0 except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN, dns.resolver.NoNameservers, dns.exception.Timeout, dns.exception.DNSException, OSError): return False def main() -> int: p = argparse.ArgumentParser(description="Test which IPv4 addresses can resolve a domain.") p.add_argument("input", help="File with IP addresses, one per line") p.add_argument("domain", help="Domain name to resolve, e.g. example.com") p.add_argument("output", help="File to write working DNS server IPs to") p.add_argument("--timeout", type=float, default=3.0, help="DNS timeout in seconds (default 3)") p.add_argument("--workers", type=int, default=50, help="Parallel queries (default 50)") args = p.parse_args() ips = load_ipv4_addresses(args.input) if not ips: print("No IPv4 addresses found in input.", file=sys.stderr) return 1 print(f"Testing {len(ips)} IPv4 address(es) against domain '{args.domain}'...") working: list[str] = [] with ThreadPoolExecutor(max_workers=args.workers) as pool: futures = {pool.submit(can_resolve, ip, args.domain, args.timeout): ip for ip in ips} for fut in as_completed(futures): ip = futures[fut] ok = False try: ok = fut.result() except Exception as e: print(f"[error] {ip}: {e}", file=sys.stderr) status = "OK " if ok else "FAIL" print(f" {status} {ip}") if ok: working.append(ip) # Preserve original input order in the output order = {ip: i for i, ip in enumerate(ips)} working.sort(key=lambda x: order[x]) with open(args.output, "w", encoding="utf-8") as f: f.write("\n".join(working) + ("\n" if working else "")) print(f"\nDone. {len(working)}/{len(ips)} resolved '{args.domain}'. Saved to {args.output}") return 0 if __name__ == "__main__": sys.exit(main())
Bridge To Freedom Aqui entramos em território de "heavy drugs". Se você está cansado de tentar "capturar" um IP público no Yandex.Cloud e similares, ou se isso é muito caro, você certamente considerou usar outros serviços deles para proxy. Entre as opções mais baratas, estão as funções serverless. São funções em alguma linguagem de programação, sem estado, cuja única tarefa é nascer, processar uma ou mais requisições de entrada e morrer. Devido ao tempo de vida limitado das funções e, mais importante, ao fato de que as requisições de entrada para tais funções passam por um gateway de API muito rigoroso do Yandex, usar XHTTP (e você sabe que XHTTP não é uma inovação dos autores do XRay, mas essa ideia foi implementada anos antes deles na forma de PHT no GoST mencionado acima?) não será possível. No entanto, ele suporta oficialmente websockets.
"Aha, então isso pode ser usado para proxy", pensou o autor do yac-ws-bridge, também conhecido como Bridge To Freedom.
Uma função serverless pode reagir a eventos como "open", "close", "ondata" e enviar dados para uma conexão já estabelecida. Por isso, o autor do yac-ws-bridge tentou primeiro criar um proxy "transparente" (que não requer modificações no cliente), mas funcionou terrivelmente mal - através do API Gateway, pacotes de dados podiam chegar em ordem incorreta, quebrando TLS e HTTP. O Telegram ainda funcionava com dificuldade, mas navegar era muito difícil, com muitas desconexões. Havia também uma opção onde, em vez de operar em fluxos TCP, ele retransmitia pacotes IP (como em uma VPN completa), para que a restauração da ordem dos dados e das partes perdidas fosse feita pela pilha TCP do sistema operacional - funcionou, mas muito lentamente. No final, a opção mais estável foi com seu próprio protocolo de multiplexação e restauração da ordem dos pacotes, e se o cliente tiver acesso não apenas ao endpoint da função serverless, mas também ao API Gateway do Yandex, a função é usada apenas para que o cliente e o servidor "encontrem" um ao outro (descubram os IDs das conexões WebSocket um do outro), e então os dados são enviados diretamente entre eles através da API do Yandex, resultando em um funcionamento muito mais rápido.
Anteontem (26/05/15) houve a seguinte atualização: "Esta versão é seriamente otimizada. O helper agora reordena os frames por SeqID ao receber, pré-registra o stream antes de enviar OPEN (portanto, os primeiros pacotes DATA após OPEN_OK não são mais perdidos), usa uma fila de escrita assíncrona para cada stream (um cliente local lento não bloqueia mais todos os outros streams) e faz half-close corretamente com FIN (respostas HTTP não são mais interrompidas). Na prática: a conexão é estabelecida visivelmente mais rápido, e o túnel funciona significativamente mais estável, especialmente em dispositivos móveis."
Eu testei, e realmente agora funciona rápido e estável o suficiente - consegui extrair 40 megabits para download e 5 para upload.
O README contém uma explicação detalhada do funcionamento, instruções para configurar a parte do servidor e fazer o upload da função serverless para o Yandex. Recomenda-se ofuscar a função antes do upload e alterar todos os caminhos dos padrões para não padrões, para que o Yandex não o bane imediatamente.
No mesmo repositório, há um cliente gráfico para isso. Como a tarefa do BTF é encaminhar fluxos TCP, ele funciona em conjunto com um proxy SOCKS ou VLESS, como v2RayN ou v2rayNG: em v2RayN/v2RayNG, você configura uma conexão SOCKS ou VLESS para o servidor, mas acessa localhost, onde o BTF está escutando. Ele, através da infraestrutura do Yandex, encaminha tudo para o seu servidor, onde também se conecta a localhost, no qual o XRay ou Dante está escutando. E tudo funciona.
O cliente é escrito em .NET MAUI, com compilações para Windows e Android. É possível compilar para iOS sozinho, mas exigirá uma Apple Developer Account. Além disso, o MAUI agora suporta compilação para Linux com backends Avalonia e GTK4, então, em teoria, é possível compilar para Linux (ou usar o cliente Go de console, que funciona em todos os lugares).
Chamadas de áudio/vídeo em mensageiros Não preciso dizer mais nada. Aqui, sem detalhes, apenas links: KillTheCensorship/Turnel (não é mais suportado, mas pode ser útil para estudar como foi feito) nil2x/cheburnet: Evasão de lista branca usando VK. TheAirBlow/Turnable: VPN core for stealthy tunneling through TURN or via SFU (até agora, a opção mais avançada). Que a força esteja com você.





