|
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 - хеш, хранящий список локальных портов (по ним происходит сравнение сокетов). |