RDot

RDot (https://rdot.org/forum/index.php)
-   Релизы/Releases (https://rdot.org/forum/forumdisplay.php?f=11)
-   -   PHP Proxy Server by Dr.Z3r0 (https://rdot.org/forum/showthread.php?t=133)

Dr.Z3r0 06.07.2010 14:32

PHP Proxy Server by Dr.Z3r0
 
Не знаю достойно ли это раздела релизы. Но запощу для его наполнения.

PHP Proxy Server v1.1

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

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

Для работы требуется библиотека socket!


Этот скрипт заливаем на сервер. Открываем через браузер (Например: http://site/path/script.php). И на этом же сервере будет запущен прокси сервер на указанном вами в настройках порту.

Кстати его както в ксакепе выкладывали, только без моего разрешение, педики =\
PHP код:

<?php  
/////////////////////////////////////////  
//       PHP Proxy Server  v1.1        //  
//         Created by Dr.Z3r0          //  
//              07.07.10              //  
/////////////////////////////////////////  
$set['port']=3333;//порт для прокси серва  
$set['mxconnect']=5;//максимальное количество одновременных подключений  
$set['lenpack']=10240;//max кол-во байт на прием/отссылку за один раз от/к клиент(а/у)  
$set['dishost']='microsoft.com';//Хост запросив который мы вырубим проксик
$set['disfile']='stop.txt';//Файл создав который рядом со скриптом мы его вырубим
/////////////////////////////////////////  
$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()));  

$break_int=0;

while(
1){    
    
//Создаем новый ресурс сокета на новое подключение  
    
if(!($msgsock=@socket_accept($sock))){  
        
socket_close($msgsock);
        
        
//Отключение скрипта
        
if($break_int++>20){
            
$break_int=0;
            if(
file_exists($set['disfile'])){
                
unlink($set['disfile']);
                break;
            }
        }
        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);  
?>


[x26]VOLAND 06.07.2010 18:53

Как, к примеру, разбиндить порт, если сервер оказался за натом, и послать на него пакет невозможно?

Dr.Z3r0 07.07.2010 00:46

Вырубить процесс из командоной строки к примеру)
Но хотя да, это можно назвать косяком, я согласен.

Fix: для отрубания скрипта создаем рядом с ним файл из конфига $set['disfile'].

pivo 07.07.2010 12:22

Насколько я понял нужна библиотека php_sockets.dll, v 1.0.0.0 верно?
Простите за глупый вопрос, куда её класть ?

upd: разобрался, спасибо за скрипт.

0w0 13.04.2013 17:15

спасибо протестирую

request 16.05.2013 16:43

Подкину идею, было бы не плохо если бы он умел работать в режиме статического проксирования хттп на другой сервер, к примеру, как это делает модуль nginx - "ngx_http_proxy_module".

HeartLESS 17.06.2014 00:13

Вложений: 1
Привет, недавно нашел такую штуку, вроде не видел тут:

допустим, вы залились на определенный хостинг, но видите возможность пробиваться дальше по http. Прав у вас почти нет, а запросы катать руками геморно.

Этот -> Вложение 471 <- маленький архивчик проксирует ваши запросы и отправляет по нужному адресу, а так же возвращает ответы целиком, что удобно, на мой взгляд.

Так как там ничего волшебного нет, а мод рерайт не всегда включен на сервере, можно легко отредактировать файл index.php или proxy.php и добить себе пару настроек (лично я просто читаю host и uri из get параметра, так же идет передача запроса дальше в сеть).

Кулибины могут допилить и поделиться более удобной версией (например редактированием ссылок на лету).

Может быть я стану сам Кулибиным =)

Enigma 17.06.2014 00:22

Цитата:

Сообщение от HeartLESS (Сообщение 36130)
Привет, недавно нашел такую штуку, вроде не видел тут:

допустим, вы залились на определенный хостинг, но видите возможность пробиваться дальше по http. Прав у вас почти нет, а запросы катать руками геморно.

Этот >-Вложение 470<- маленький архивчик проксирует ваши запросы и отправляет по нужному адресу, а так же возвращает ответы целиком, что удобно, на мой взгляд.

Так как там ничего волшебного нет, а мод рерайт не всегда включен на сервере, можно легко отредактировать файл index.php или proxy.php и добить себе пару настроек (лично я просто читаю host и uri из get параметра, так же идет передача запроса дальше в сеть).

Кулибины могут допилить и поделиться более удобной версией (например редактированием ссылок на лету).

Может быть я стану сам Кулибиным =)

Как раз была необходимость в таком скрипте недавно, заюзал PHProxy++, с phpmyadmin работает нормально.

upd: правда phpproxy++ частично работает через гет и оставляет в логах довольно заметные записи.

----

Также советую глянуть статью https://rdot.org/forum/showthread.php?t=589, прочитал через неделю после поста. В моём случае именно это помогло бы, и не пришлось бы гадить в access.log


Часовой пояс GMT +3, время: 04:45.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot