DNS-туннелинг или халявный dialup

Дмитрий Докучаев aka Forb

Xakep, номер #051, стр. 051-058-2


Спаситель UDP

Мне пришла в голову следующая мысль: а что, если провайдер позволяет светить 53-ий порт куда угодно, заботливо оставляя его для DNS-обмена. Решив проверить эту фичу, я написал простенькую систему клиент-сервер, передающую данные и записывающую их в логфайл. Оставалось проверить успешную передачу и радоваться жизни. Однако не стоит сильно обнадеживаться. Может оказаться так, что провайдер закроет все порты, даже 53-ий UDP. Но вернемся к нашей утилите. Я опишу работу сервера, а клиент ты без труда напишешь и сам (по аналогии). Для кодинга я выбрал язык Perl, так как мог свободно пользовать Windows-клиент и *nix-сервер для работы с udp-сокетом.

#!/usr/bin/perl

## Checker for open udp ports

use IO::Socket;

$sock=IO::Socket::INET->new(LocalPort=>53,Proto=>'udp',Reuse=>1) || die "cant create socket $!\n";

while($sock->recv($data,10000,0)) {

open(TF,">accept");

print TF "GOT msg $data\n";

close(TF);

}

Этот сервер устанавливаем на нашем шелле. Он, как ты, наверное, уже догадался, будет принимать данные на 53-ий udp-порт. Аналогичный клиент пошлет запрос на сервер, и если он успешно дойдет, то будет записан в файл "accept". Пролистав его, ты поймешь, светится ли порт. Если порт будет открыт, возможно написать свой сервер, который следит за udp-подключениями, создает tcp-соединение и перенаправляет tcp в udp и наоборот. То есть осуществить туннелинг по следующей схеме: локальный клиент, следящий tcp-порт и перенаправляющий все данные с него на udp-порт удаленного сервера, который, в свою очередь, порождает tcp-соединение с возвратом всех данных посредством udp-датаграмм.

Несмотря на кажущуюся сложность схемы, все довольно просто. Пишется сервер, который будет находиться на шелле с хорошим каналом в инет, и клиент, который будет запускаться непосредственно с домашней машины. Для реализации этой схемы нам потребуется:

a) ActivePerl, если у тебя Windows (в случае с NTSX, юзание Windows недопустимо).

б) Shell в России или в зарубежье.

в) Доступ к Proxy-серверу с доступным CONNECT методом (необязательно).

Если у тебя есть все три составляющие, то ты можешь использовать мой проект, позволяющий делать туннель для IRC. Конечно, это неполноценно, но халявный IRC меня вполне устраивает, и потеря пакетов там незначительная. Сам сервер и клиент выполнены несколько по-разному. Тут я попытаюсь рассказать основной принцип работы сервера и клиента с небольшими фрагментами кода.

Сервер: udpserver.pl

Прежде чем писать сервер, я тщательно обдумал, что от него требуется. А требовалось от него:

1) Многопоточность.

2) Гибкое закрытие сокета при обрыве его клиентом.

3) Проверка всех клиентов на живучесть с помощью keep-alive мессаг.

В какой-то мере я добился выполнения всех трех пунктов. Чтобы ты смог разобраться в коде, я расскажу тебе об основных скалярах и векторах в моей программе:

%ports - хеш, хранящий список локальных портов (по ним происходит сравнение сокетов).

Назад на стр. 051-058-1  Содержание  Вперед на стр. 051-058-3