A continuação do
artigo sobre como eu consegui organizar um túnel VPN direto entre dois computadores localizados atrás de provedores de NAT. O último artigo descreveu o processo de organização de uma conexão usando terceiros - um intermediário (um VPS alugado agindo como algo como um servidor STUN e um transmissor de dados do nó para uma conexão). Neste artigo, mostrarei como ficar sem o VPS, mas os intermediários permaneceram e eles eram o servidor STUN e o Yandex.Disk ...

1. Introdução
Depois de ler os comentários do último post, percebi que a principal desvantagem da implementação era o uso de um intermediário - um terceiro (VPS) que indicava os parâmetros atuais do nó, onde e como se conectar. Dadas as recomendações para usar este STUN (existem
muitas ) para determinar os parâmetros de conexão atuais. Antes de tudo, decidi examinar o conteúdo dos pacotes usando o TCPDump quando o servidor STUN estava trabalhando com clientes e recebia conteúdo completamente ilegível. Pesquisando no protocolo, vi um
artigo descrevendo o protocolo . Percebi que não posso implementar a solicitação no servidor STUN e coloquei a ideia na "caixa distante".
Teoria
Recentemente, tive que instalar um servidor STUN no Debian a partir de um pacote
e nas dependências vi o pacote stun-client, mas de alguma forma não atribui nenhuma importância a isso. Mais tarde, porém, lembrei-me do pacote stun-client e decidi descobrir como ele funciona, pesquisando no Google e Poindeksiv:
Em resposta, recebi:
Cliente STUN versão 0.97
Porta aberta 21234 com fd 3
Porta aberta 21235 com fd 4
Codificando mensagem de atordoamento:
Codificação ChangeRequest: 0
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Mensagem de atordoamento recebida: 92 bytes
MappedAddress = <Meu IP>: 2885
SourceAddress = 216.93.246.18//478
ChangedAddress = 216.93.246.17lla479
Atributo desconhecido: 32800
ServerName = Vovida.org 0.98-CPC
Mensagem recebida do tipo 257 id = 1
Codificando mensagem de atordoamento:
Codificação ChangeRequest: 0
Prestes a enviar msg de len 28 para 216.93.246.17lla478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
Codificação ChangeRequest: 0
Sobre o envio de msg de len 28 para <My IP>: 2885
Mensagem de atordoamento recebida: 28 bytes
ChangeRequest = 0
Mensagem recebida do tipo 1 id = 11
Codificando mensagem de atordoamento:
Codificação ChangeRequest: 0
Prestes a enviar msg de len 28 para 216.93.246.17lla478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Mensagem de atordoamento recebida: 92 bytes
MappedAddress = <Meu IP>: 2885
SourceAddress = 216.93.246.17lla479
ChangedAddress = 216.93.246.18 {478
Atributo desconhecido: 32800
ServerName = Vovida.org 0.98-CPC
Mensagem recebida do tipo 257 id = 10
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 4
Sobre enviar msg de len 28 para 216.93.246.18 opin478
Codificando mensagem de atordoamento:
ChangeRequest de codificação: 2
Sobre enviar msg de len 28 para 216.93.246.18 opin478
teste I = 1
teste II = 0
teste III = 0
teste I (2) = 1
é nat = 1
IP mapeado mesmo = 1
gancho de cabelo = 1
porta do preservador = 0
Primário: mapeamento independente, filtro dependente de porta, porta aleatória, gancho de cabelo
O valor de retorno é 0x000006
String com valor
MappedAddress = <Meu IP>: 2885
exatamente o que você precisa! Ele exibia o status atual da conexão na porta UDP local 21234. Mas isso é apenas metade da batalha, surgiu a questão de como transferir esses dados para um host remoto e estabelecer uma conexão VPN. Usando o protocolo de email, talvez Telegram ?! Existem muitas opções e eu decidi usar o Yandex.Disk, pois me deparei com
um artigo sobre como o Curl funciona através do WebDav com o Yandex.Disk . Depois de pensar na implementação, cheguei a esse esquema:
- Sinalizar que os nós estão prontos para estabelecer uma conexão pela presença de um arquivo específico com carimbo de data / hora no Yandex.disk;
- Se os nós estiverem prontos, obtenha os parâmetros atuais do servidor STUN;
- Carregar parâmetros atuais para Yandex.Disk;
- Verifique a disponibilidade e leia os parâmetros de um site remoto a partir de um arquivo no Yandex.Disk;
- Estabeleça uma conexão com um host remoto usando o OpenVPN.
Prática
Depois de um pouco de reflexão, levando em conta a experiência do artigo anterior, escrevi um script rápido. Vamos precisar de:
Na verdade, o próprio script:
Opção inicial
Para executar o script, você precisa:
- Copie para a área de transferência e cole no editor, por exemplo:
- especifique o nome de usuário e a senha do Yandex.Disk.
- no campo "--ifconfig 10.45.54. (1 ou 2) 255.255.255.252" especifique o endereço IP interno da interface
- crie secret.key com o comando:
- torne o script executável:
- execute o script:
onde nZbVGBuX5dtturD é o ID da conexão gerado aqui
No nó remoto, faça o mesmo, exceto na geração de secret.key e na conexão de ID, eles devem ser idênticos.
Versão atualizada (para operação correta, a hora deve ser sincronizada):
cat vpn10.sh
Para executar o script, você precisa:
- Copie para a área de transferência e cole no editor, por exemplo:
- especifique o login (segunda linha) e a senha do Yandex.Disk (terceira linha).
- especifique o endereço IP interno do túnel (quarta linha).
- torne o script executável:
- execute o script:
onde nZbVGBuX5dtturD é o ID da conexão gerado aqui
No nó remoto, faça o mesmo, especifique o endereço IP interno correspondente do túnel e a conexão de ID.
Para iniciar o script na inicialização, eu uso o comando "nohup / <caminho para o script> /vpn10.sh nZbVGBuX5dtturD> /var/log/vpn10.log 2> / dev / null &" contido no arquivo /etc/rc.local
Conclusão
O script funciona, testado no Ubuntu 18.04 e Debian 9. Você pode usar qualquer outro serviço como transmissor, mas, por experiência, usei o Yandex.Disk.
No decorrer das experiências, verificou-se que alguns tipos de provedores de NAT não permitem uma conexão. Principalmente com operadoras móveis onde os torrents estão bloqueados.
Pretendo finalizar em termos de:
- A geração automática de secret.key toda vez que você inicia, criptografa e copia para o Yandex.Disk para transferir para um host remoto (levado em conta na versão atualizada)
- Atribuir automaticamente endereços IP de interface
- Criptografia de dados antes de carregar no Yandex.Disk
- Otimização de código
Pode haver IPv6 em todas as casas!