ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > PHP, PERL, MySQL, JavaScript
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

PHP Proxy Server
  #1  
Старый 22.02.2008, 17:10
Аватар для Dr.Z3r0
Dr.Z3r0
Leaders of The World
Регистрация: 06.07.2007
Сообщений: 246
Провел на форуме:
2030482

Репутация: 1796
По умолчанию PHP Proxy Server

PHP Proxy Server v1.0 pre-realase

Вообщем вот проксик написал.
Писал для себя скажем так для развития. Интересовала библиотека socket. Вот собственно из этого и получился прокси серв.

Возможности эт собственно сам прокси сервер, тунелирование, логирование и пр.

Для работы требуется библиотека socket!
PHP код:
<?php
/////////////////////////////////////////
//  PHP Proxy Server v1.0 pre-realase  //
//         Created by I-I()/Ib         //
//              22.02.08               //
/////////////////////////////////////////
$set['port']=3333;//порт для прокси серва
$set['mxconnect']=5;//максимальное количество одновременных подключений
$set['lenpack']=10240;//max кол-во байт на прием/отссылку за один раз от/к клиент(а/у)
$set['dishost']='microsoft.com';//Хост запросив который мы вырубим проксик
/////////////////////////////////////////
$set['usagent']='Mozilla/5.0 ( Windows; U; AOL 5.0; TWRAITH )';//Заменять User-Agent на это... (false оставить прежним)
$set['xforwadfor']=0;//X-Forwarded-For: 0-не указывать/удалить существующий, 1-указывать реальный, 2-генерить случайно
$set['referer']=0;//Referer: 0-удалять, 1-оставить
$set['chngprx']=0;//0-Менять заголовок указывающий на то что используется прокси сервер, 1-не менять
$set['addcapt']=0;//1-Добавлять заголовок указывающий версию этого прокси серва, 0-не добалять
/////////////////////////////////////////
$set['allip']=true;//true-прокси для всех ип, false только для $set['acssip']
$set['acssip']=array('127.0.');//маски разрешенных ип...
/////////////////////////////////////////
$set['logerror']='error.log';//Файл лога ошибок, false-не писать...
$set['logacess']='acess.log';//Лог запросов прокси, false-не писать...
$set['savacess']=1;//0-Указать только ип и время, 1-указать ип время и удаленный хост
/////////////////////////////////////////
$set['tnlnbld']=false;//Включить поддержку тунелирования проксиком
$set['fltnl']='proxy.txt';//Файл список всех прокси серверов
$set['rntnl']=true;//Рандомно изменять порядок серверов
$set['ndtnl']=false;//Последний сервер в списке всегда конечный
$set['nmtnl']='Data-Send';//Имя параметра в заголвке в котором будет передаваться весь список прокси
/////////////////////////////////////////

function parse_packet(&$packet, &$host, &$error$ip){
    global 
$set;

    
$error=false;
    
//Валидность ипа
    
if(!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/',$ip)){
        
$error='Proxy don\'t understend your ip. Sorry...';
    }else{
        
//Разрешен ли проксик для всех ипов
        
if(!$set['allip']){
            
$error='This proxy can not used from anything ip. Acsess denieded.';
            foreach(
$set['acssip'] as $key){
                if(
preg_match('/'.preg_quote($key).'/',$ip)){
                    
$error=false;
                    break;
                }
            }
        }
    }

    if(!
$error){
        
//Проверка валидности пакета
        
if(!preg_match('/^(GET|POST|HEAD) \S+ HTTP\/1\.[1|0]\r\n([\w-]+: [\w|\W]+\r\n)+\r\n[\w|\W]*/i',$packet))$error='Proxy don\'t understand your packet. Sorry...';
        else{
            
//Выдираем имя хоста
            
if(!preg_match('/Host: ([^\r\n]+)/i',$packet,$tmp))$error='In your packet don\'t writing remote host. Sorry...';
            else{
                if(!
preg_match('/^[\w\.\-:]+$/',$tmp[1]))$error='Remote host not valid. Sorry...';
                else{
                    
$host=$tmp[1];
                    
$tmp='';
                    
//Лог обращений к проксику
                    
if($set['logacess']){
                        
$fp=fopen($set['logacess'], 'a');
                        
fputs($fp,$ip.' ['.date('H:i d.m.Y',time()).'] '.$host."\r\n");
                        
fclose($fp);
                    }
                    
//Меняем User-Agent
                    
if($set['usagent'])$packet=preg_replace('/User-Agent: [^\r\n]+/i','User-Agent: '.$set['usagent'],$packet);
                    
//Меняем Referer
                    
if($set['referer']===0)$packet=preg_replace('/Referer: [^\r\n]+\r\n/i','',$packet);
                    
//Меняем лишние заголовки
                    
if($set['chngprx']===0)$packet=preg_replace('/Proxy-Connection: /','Connection: ',$packet);
                    
//Операции с X-Forwarded-For
                    
if($set['xforwadfor']===0)$packet=preg_replace('/X-Forwarded-For: [^\r\n]+\r\n/i','',$packet);
                    else if(
$set['xforwadfor']===1)$packet=preg_replace('/Host: ([^\r\n]+)/i','Host: \\1'."\r\n".'X-Forwarded-For: '.$ip,$packet);
                    else if(
$set['xforwadfor']===2)$packet=preg_replace('/Host: ([^\r\n]+)/i','Host: \\1'."\r\n".'X-Forwarded-For: '.gen_ran_ip(),$packet);
                    
//Указываем версию проксика
                    
if($set['addcapt']===1)$packet=preg_replace('/Host: ([^\r\n]+)/i','Host: \\1'."\r\n".'Use-Proxy: PPS v1.0',$packet);
                }
            }
        }
    }

    if(!
$error)return true;
    else return 
false;
}

function 
gen_ran_ip(){
    
$ip=rand(80,255);
    
$ip.='.'.rand(80,255);
    
$ip.='.'.rand(80,255);
    
$ip.='.'.rand(80,255);

    return 
$ip;
}

function 
eror_rep($error,$ip){
    global 
$set;

    if(
$error){
        
//Лог ошибок
        
if($set['logerror']){
            
$fp=fopen($set['logerror'], 'a');
            
fputs($fp,$ip.' ['.date('H:i d.m.Y',time()).']'.$error."\r\n");
            
fclose($fp);
        }
        
$packet_ret='HTTP/1.1 500 Error
Server: PPS v1.0
Connection: Close
Transfer-Encoding: chunked
Content-Type: text/html

'
;
        
$tmp='<html>
<head>
<title>Proxy Error...</title>
<head>
<body>
Proxy return error:<br>
'
.$error.'
</body>
</html>'
;
        
$packet_ret.=dechex(strlen($tmp))."\r\n".$tmp."\r\n".'0'."\r\n\r\n";
        return 
$packet_ret;
    }else return 
false;

}

error_reporting(0);
set_time_limit(0);
ignore_user_abort(true);
//Подключенна ли данная библиотека
if(!function_exists('socket_create'))die("socket_create() failed, reason: socket library is not loaded");
//Создание сокета
if(!($sock=@socket_create(AF_INETSOCK_STREAMSOL_TCP)))die("socket_create() failed, reason: ".socket_last_error()."<br>\r\n".socket_strerror(socket_last_error()));
//Открываем порт
if(!(@socket_bind($sock'127.0.0.1'$set['port'])))die("socket_bind() failed, reason: ".socket_last_error()."<br>\r\n".socket_strerror(socket_last_error()));
//Ждем подключений
if(!@socket_listen($sock$set['mxconnect']))die("socket_listen() failed, reason: ".socket_last_error()."<br>\r\n".socket_strerror(socket_last_error()));

while(
1){
    
//Создаем новый ресурс сокета на новое подключение
    
if(!($msgsock=@socket_accept($sock))){
        
socket_close($msgsock);
        continue;
    }
    
//Узнаем ип клиента
    
$ip='';
    if(!@
socket_getpeername($msgsock,$ip)){
        
socket_close($msgsock);
        continue;
    }

    
$zzz='';
    
$buf='';
    
$pak='';
    
//Читаем пакет от клиента
    
while(1){
        
$tmp=@socket_read($msgsock$set['lenpack'],PHP_BINARY_READ);
        if(!empty(
$tmp)){
            if(!
is_array($pak)){
                
$buf.=$tmp;
                
//Прием заголовка окончен
                
if(preg_match('/\r\n\r\n/i',$buf)){
                    
//Определяемся с методом передачи данных
                    
if(preg_match('/^(GET|POST|HEAD)/i',$buf,$zzz)){
                        
$pak['type']=$zzz[1];
                        
$zzz='';
                        
//Для GET и HEAD одного заголовка достаточно
                        
if(($pak['type']==='GET')||($pak['type']==='HEAD')){
                            
$pak['header']=$buf;
                            
$pak['receiv']='';
                            break;
                        }else{
                            
//Выдираем Content-Length для метода POST
                            
if(preg_match('/Content-Length: (\d+)\r\n/i',$buf,$zzz)){
                                
$pak['length']=$zzz[1];
                                
//Делим пакет на заголовок и данные
                                
preg_match('/([\w|\W]+)\r\n\r\n([\w|\W]*)/i',$buf,$zzz);
                                
$pak['header']=$zzz[1];
                                
$pak['receiv']=$zzz[2];
                                
$zzz='';
                                if(
strlen($pak['receiv'])==$pak['length'])break;
                            }else break;
                        }
                    }else{
                        
$pak['header']='';
                        
$pak['receiv']='';
                        
$pak['length']='0';
                        break;
                    }
                }
            }else{
                
//Собираем до конца все данные
                
$pak['receiv'].=$tmp;
                if(!(
strlen($pak['receiv'])<$pak['length']))break;
            }
            
$tmp='';
        }
    }
    
$buf=$pak['header']."\r\n\r\n".$pak['receiv'];

    
$tmp='';
    if(
parse_packet($buf,$host,$error,$ip)){
        
//Вырубить проксик
        
if($host===$set['dishost']){
            
socket_close($msgsock);
            
socket_close($sock);
            die();
        }

        
//Поддержка тунелирования
        
$proxy='';
        if(
$set['tnlnbld']){
            
//Передан ли параметр с прокси сервами
            
if(preg_match('/'.preg_quote($set['nmtnl']).': ([^\r\n]+)/',$buf,$tmp)){
                
$tmp=explode('|',base64_decode($tmp[1]));
                if(!empty(
$tmp)){
                    
//Убираем адрес следующего прокси сервера
                    
$host=$tmp[0];
                    if(
count($tmp)>1){
                        
$proxy='';
                        for(
$i=1;$i<count($tmp);$i++)$proxy.=$tmp[$i].'|';
                        
$proxy=substr($proxy,0,strlen($proxy)-1);
                        
$proxy=base64_encode($proxy);
                        
//Записываем это все в заголовок
                        
$buf=preg_replace('/'.preg_quote($set['nmtnl']).': ([^\r\n]+)/i',$set['nmtnl'].': '.$proxy,$buf);
                        
$tmp='';
                    }else{
                        
$buf=preg_replace('/'.preg_quote($set['nmtnl']).': ([^\r\n]+)\r\n/i','',$buf);
                    }
                }
                
$tmp='';
            }else{
                
//Существует ли файл со списоком(предполагается что этот сервер - 1ый)
                
if(file_exists($set['fltnl'])){
                    
$tmp=file($set['fltnl']);
                    
$host=trim($tmp[0]);
                    if(
count($tmp)>1){
                        
$proxy='';
                        
$xxxx='';
                        
//Перемешивание
                        
if($set['rntnl']){
                            
//Конечный проксик один и тот же всегда
                            
if($set['ndtnl']){
                                
$yyyy=$tmp[count($tmp)-1];
                                for(
$i=1;$i<count($tmp)-1;$i++)$xxxx[$i-1]=trim($tmp[$i]);
                                
shuffle($xxxx);
                                
$xxxx[]=$yyyy;
                                
$yyyy='';
                            }else{
                                for(
$i=1;$i<count($tmp);$i++)$xxxx[$i-1]=trim($tmp[$i]);
                                
shuffle($xxxx);
                            }
                        }else{
                            for(
$i=1;$i<count($tmp);$i++)$xxxx[$i-1]=trim($tmp[$i]);
                        }
                        
$tmp='';
                        foreach(
$xxxx as $tmp)$proxy.=$tmp.'|';
                        
$proxy=substr($proxy,0,strlen($proxy)-1);
                        
$proxy=base64_encode($proxy);
                        
//Записываем это все в заголовок
                        
$buf=preg_replace('/Host: ([^\r\n]+)/i','Host: \\1'."\r\n".$set['nmtnl'].': '.$proxy,$buf);
                        
$xxxx='';
                    }
                    
$tmp='';
                }
            }
        }
        
$proxy='';
        
$tmp='';

        
$port=80;
        
//Если в хосте указан порт то его нужно выдрать
        
if(preg_match('/^([^:]+)(:\d+)*$/',$host,$tmp)){
            
$host=$tmp[1];
            if(isset(
$tmp[2])){
                
$port=$tmp[2];
                
preg_match('/^:(\d+)$/',$port,$tmp);
                
$port=$tmp[1];
            }
        }

        
$tmp='';
        
//Если в кач-ве хоста передано имя домена, то его нуно преобразовать в айпишник...
        
if(!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/',$host)){
            
$tmp=gethostbyname($host);
            if(
$tmp===$host){
                
//Имя домена не найденно
                
$tmp=eror_rep('Remote server not found. Sorry...',$ip);
                
socket_write($msgsock,$tmp,strlen($tmp));
                
$error=true;
            }else 
$host=$tmp;
            
$tmp='';
        }

        if(!
$error){
            
//Посылка запроса на удаленный сервер
            
$sock2=socket_create(AF_INETSOCK_STREAMSOL_TCP);
            
//Подключение
            
if(!(@socket_connect($sock2$host$port))){
                
$tmp=eror_rep('Can\'t connect ro remote server. Reason:'."<br>\r\n".socket_strerror(socket_last_error()),$ip);
                
socket_write($msgsock,$tmp,strlen($tmp));
                break;
            }else{
                
//Отправка пакета
                
if(!(@socket_write($sock2$bufstrlen($buf)))){
                    
$tmp=eror_rep('Can\'t send packet ro remote server. Reason:'."<br>\r\n".socket_strerror(socket_last_error()),$ip);
                    
socket_write($msgsock,$tmp,strlen($tmp));
                    break;
                }else{
                    
//Чтение
                    
while($tmp=@socket_read($sock2$set['lenpack'])){
                        
//Отправка приянтых данных клиенту
                        
if(!$tmp)break;
                        
socket_write($msgsock,$tmp,strlen($tmp));
                    }
                }
            }
            
socket_close($sock2);
        }
    }else{
        
//Отправка текста ошибки клиенту
        
$tmp=eror_rep($error."<br>\r\n",$ip);
        
socket_write($msgsock,$tmp,strlen($tmp));
    }
    
$ip='';
    
$buf='';
    
$pak='';
    
socket_close($msgsock);
}
socket_close($sock);
?>
__________________
Кто я?..
 
Ответить с цитированием

  #2  
Старый 22.02.2008, 17:14
Аватар для bul.666
bul.666
Banned
Регистрация: 06.06.2006
Сообщений: 944
Провел на форуме:
3986705

Репутация: 1403


Отправить сообщение для bul.666 с помощью ICQ
По умолчанию

Цитата:
$ip='';
$buf='';
$pak='';
Не лучшебы использовать unset() ?
 
Ответить с цитированием

  #3  
Старый 22.02.2008, 17:22
Аватар для DIAgen
DIAgen
Познавший АНТИЧАТ
Регистрация: 02.05.2006
Сообщений: 1,191
Провел на форуме:
7364332

Репутация: 1276


По умолчанию

Я тебе уже говорил что скриптик прикольный, только жалко его не возможно поставить на сервак...

P.S>А да еще заметил одну фишку с socket, когда работаешь с протоколами например с SMTP or FTP то команды посылаются нормально через socket, если посылать запросы HTTP сначало один запрос с заголовков, а потом второй, то первый пройдет, а второй почему то не хочет проходить.. фиг знает почему, это было так маленькое отступление наболевшего
 
Ответить с цитированием

  #4  
Старый 22.02.2008, 19:23
Аватар для Isis
Isis
Флудер
Регистрация: 20.11.2006
Сообщений: 3,316
Провел на форуме:
16641028

Репутация: 2371


По умолчанию

Цитата:
Сообщение от bul.666  
Не лучшебы использовать unset() ?
Вообще-то все правильно
Посмотри...он эти переменные просто определяет что они существуют для дальнейшего использования без ошибок !
 
Ответить с цитированием

  #5  
Старый 24.02.2008, 12:58
Аватар для xaker-boss
xaker-boss
Участник форума
Регистрация: 06.03.2007
Сообщений: 283
Провел на форуме:
1547094

Репутация: 120
Отправить сообщение для xaker-boss с помощью ICQ
По умолчанию

Отлично работает, спасибо
 
Ответить с цитированием

  #6  
Старый 24.02.2008, 13:32
Аватар для ElteRUS
ElteRUS
Постоянный
Регистрация: 11.10.2007
Сообщений: 406
Провел на форуме:
7215020

Репутация: 1423
По умолчанию

Цитата:
Сообщение от DIAgen  
если посылать запросы HTTP сначало один запрос с заголовков, а потом второй, то первый пройдет, а второй почему то не хочет проходить.. фиг знает почему, это было так маленькое отступление наболевшего
Для каждого HTTP запроса нужно создавать сокет заново. Клиент посылает 1 запрос - получает от сервера 1 ответ - связь окончена. Когда-то тут цитировали рфц по этому поводу, не помню уже где )
 
Ответить с цитированием

  #7  
Старый 24.02.2008, 13:49
Аватар для heks
heks
Постоянный
Регистрация: 24.08.2007
Сообщений: 474
Провел на форуме:
1484154

Репутация: 126
Отправить сообщение для heks с помощью ICQ
По умолчанию

у меня что то не работает как можно проверить присутствует ли библиотека сокет

Последний раз редактировалось heks; 24.02.2008 в 14:02..
 
Ответить с цитированием

  #8  
Старый 24.02.2008, 14:14
Аватар для Dr.Z3r0
Dr.Z3r0
Leaders of The World
Регистрация: 06.07.2007
Сообщений: 246
Провел на форуме:
2030482

Репутация: 1796
По умолчанию

По идее скрипт должен вырубаться с сообщением:
"socket_create() failed, reason: socket library is not loaded"
__________________
Кто я?..
 
Ответить с цитированием

  #9  
Старый 24.02.2008, 14:15
Аватар для Pernat1y
Pernat1y
Постоянный
Регистрация: 20.12.2007
Сообщений: 577
Провел на форуме:
1636674

Репутация: 171


По умолчанию

посмотри лог ошибок апача, и проверь, подключен-ли php_sockets.dll расширениях (php.ini)
 
Ответить с цитированием

  #10  
Старый 24.02.2008, 23:44
Аватар для nc.STRIEM
nc.STRIEM
Members of Antichat - Level 5
Регистрация: 05.04.2006
Сообщений: 1,066
Провел на форуме:
3493315

Репутация: 1228


Отправить сообщение для nc.STRIEM с помощью ICQ
По умолчанию

все хорошо, но для каждого нового подключения необходимо создавать новый паток.
В твоем варианте все работает, но вот скорсть страдает, т.к. все запросы становяться в очередь и ждут окончания выполнения придыдущего. А есле это будет скачка тяжолого файла? вобщем думаю понял что я имел ввиду
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Что такое Php? PAPA212 Болталка 13 28.12.2007 20:44
Живые прокси xdx ICQ 111 15.04.2007 13:10
Безопасность в Php, Часть Iii k00p3r Чужие Статьи 0 11.07.2005 19:02
Защищаем Php. Шаг за шагом. k00p3r Чужие Статьи 0 13.06.2005 11:31



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ