Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   PHP Proxy Server (https://forum.antichat.xyz/showthread.php?t=62441)

Dr.Z3r0 22.02.2008 17:10

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);
?>


bul.666 22.02.2008 17:14

Цитата:

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

DIAgen 22.02.2008 17:22

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

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

Isis 22.02.2008 19:23

Цитата:

Сообщение от bul.666
Не лучшебы использовать unset() ?

Вообще-то все правильно :)
Посмотри...он эти переменные просто определяет что они существуют для дальнейшего использования без ошибок !

xaker-boss 24.02.2008 12:58

Отлично работает, спасибо

ElteRUS 24.02.2008 13:32

Цитата:

Сообщение от DIAgen
если посылать запросы HTTP сначало один запрос с заголовков, а потом второй, то первый пройдет, а второй почему то не хочет проходить.. фиг знает почему, это было так маленькое отступление наболевшего:)

Для каждого HTTP запроса нужно создавать сокет заново. Клиент посылает 1 запрос - получает от сервера 1 ответ - связь окончена. Когда-то тут цитировали рфц по этому поводу, не помню уже где )

heks 24.02.2008 13:49

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

Dr.Z3r0 24.02.2008 14:14

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

Pernat1y 24.02.2008 14:15

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

nc.STRIEM 24.02.2008 23:44

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

Dr.Z3r0 25.02.2008 00:08

Вообще этот прокси расчитан на 5 коннектов одновременно по дефолту(что можно поменять в настройках) раз, а во вторых многопоточность в пхп - это извращение как таковое...

nc.STRIEM 25.02.2008 00:38

Цитата:

Вообще этот прокси расчитан на 5 коннектов одновременно по дефолту(что можно поменять в настройках)
Эт я видел, но каая разница скок конектов, начнеш через него файл скачивать и все.... один конект...

Цитата:

а во вторых многопоточность в пхп - это извращение как таковое...
Согласен, но а что делать..

sabe 18.07.2008 20:47

Цитата:

socket_bind() failed, reason: 98
Address already in use
как исправить ?

Developer 18.07.2008 22:50

Как юзать можно? Реально, чтобы прописать в браузере ИП сайта и порт 80 где он стоит и чтобы работал?

Dr.Z3r0 19.07.2008 18:56

Цитата:

Цитата:

socket_bind() failed, reason: 98
Address already in use
как исправить ?
Измени на что нить другое:
$set['port']=3333;//порт для прокси серва
PS Кхм а перевести самому слабо было?)


Цитата:

Как юзать можно? Реально, чтобы прописать в браузере ИП сайта и порт 80 где он стоит и чтобы работал?
Правда хер пойми че те надо. Но вообщем алгоритм юзания следующий. Берем скрипт этого проксика засовываем на какой нить хост. Запускаем этот скрипт (как запускать писать не буду). Если запустился без ошибок значит все ок. Далее в браузере пишем в качестве адреса прокси IP адрес хоста и порт который вы указали в настройках (для танкистов $set['port']). И можете спокойно работать через этот проксег.

PS Ляд ну пожалуйста научитесь писать нормально чего вам надо, в конце концов оно надо вам. Почему мы должны угадывать что вам нужно?

DVD_RW 22.08.2008 16:43

эм...за нубский вопрос сорри... а на coolpage.biz пойдёт? ><

Romaxa55 25.08.2008 02:14

Пишет
Цитата:

socket_create() failed, reason: 0
Success
Проблеммаа с самим хостингом?

Скорей всего сокет не подключин на хосте

sharky_fish 23.12.2008 22:43

А на каком бесплатном хостинге работает? Может ктото подсказать?
Или можно ПМ. Спасибо.

ntldr 23.12.2008 23:22

искал давно!

sharky_fish 23.12.2008 23:43

Наверное уже не судьба получить ответ :)


Время: 05:18