Perl实现的Linux下socket代理服务器
大家提供了许多linux开代理的方法,一般用到python等语言,一些服务器可能不会安装,然而perl可以说是linux标配的语言,给大家一款Perl语言的socket代理,代码非常少,而且还支持密码,效果还是不错,感觉很稳定。
#!/usr/bin/perl
$auth_enabled=0;
$auth_login="hidden";
$auth_pass="hidden";
$port=44269;
useIO::Socket::INET;
$SIG{'CHLD'}='IGNORE';
$bind=IO::Socket::INET->new(Listen=>10,Reuse=>1,LocalPort=>$port)ordie"Нельзязабиндитьпорт$port\n";
while($client=$bind->accept()){
$client->autoflush();
if(fork()){$client->close();}
else{$bind->close();new_client($client);exit();}
}
subnew_client{
local$t,$i,$buff,$ord,$success;
local$client=$_[0];
sysread($client,$buff,1);
if(ord($buff)==5){
sysread($client,$buff,1);
$t=ord($buff);
unless(sysread($client,$buff,$t)==$t){return;}
$success=0;
for($i=0;$i<$t;$i++){
$ord=ord(substr($buff,$i,1));
if($ord==0&&!$auth_enabled){
syswrite($client,"\x05\x00",2);
$success++;
break;
}
elsif($ord==2&&$auth_enabled){
unless(do_auth($client)){return;}
$success++;
break;
}
}
if($success){
$t=sysread($client,$buff,3);
if(substr($buff,0,1)=='\x05'){
if(ord(substr($buff,2,1))==0){
($host,$raw_host)=socks_get_host($client);
if(!$host){return;}
($port,$raw_port)=socks_get_port($client);
if(!$port){return;}
$ord=ord(substr($buff,1,1));
$buff="\x05\x00\x00".$raw_host.$raw_port;
syswrite($client,$buff,length($buff));
socks_do($ord,$client,$host,$port);
}
}
}else{syswrite($client,"\x05\xFF",2);};
}
$client->close();
}
subdo_auth{
local$buff,$login,$pass;
local$client=$_[0];
syswrite($client,"\x05\x02",2);
sysread($client,$buff,1);
if(ord($buff)==1){
sysread($client,$buff,1);
sysread($client,$login,ord($buff));
sysread($client,$buff,1);
sysread($client,$pass,ord($buff));
if($logineq$auth_login&&$passeq$auth_pass){
syswrite($client,"\x05\x00",2);
return1;
}else{syswrite($client,"\x05\x01",2);}
}
$client->close();
return0;
}
subsocks_get_host{
local$client=$_[0];
local$t,$ord,$raw_host;
local$host="";
sysread($client,$t,1);
$ord=ord($t);
if($ord==1){
sysread($client,$raw_host,4);
@host=$raw_host=~/(.)/g;
$host=ord($host[0]).".".ord($host[1]).".".ord($host[2]).".".ord($host[3]);
}elsif($ord==3){
sysread($client,$raw_host,1);
sysread($client,$host,ord($raw_host));
$raw_host.=$host;
}elsif($ord==4){
#ipv6-notsupported
}
return($host,$t.$raw_host);
}
subsocks_get_port{
local$client=$_[0];
local$raw_port,$port;
sysread($client,$raw_port,2);
$port=ord(substr($raw_port,0,1))<<8|ord(substr($raw_port,1,1));
return($port,$raw_port);
}
subsocks_do{
local($t,$client,$host,$port)=@_;
if($t==1){socks_connect($client,$host,$port);}
elsif($t==2){socks_bind($client,$host,$port);}
elsif($t==3){socks_udp_associate($client,$host,$port);}
else{return0;}
return1;
}
subsocks_connect{
my($client,$host,$port)=@_;
my$target=IO::Socket::INET->new(PeerAddr=>$host,PeerPort=>$port,Proto=>'tcp',Type=>SOCK_STREAM);
unless($target){return;}
$target->autoflush();
while($client||$target){
my$rin="";
vec($rin,fileno($client),1)=1if$client;
vec($rin,fileno($target),1)=1if$target;
my($rout,$eout);
select($rout=$rin,undef,$eout=$rin,120);
if(!$rout&&!$eout){return;}
my$cbuffer="";
my$tbuffer="";
if($client&&(vec($eout,fileno($client),1)||vec($rout,fileno($client),1))){
my$result=sysread($client,$tbuffer,1024);
if(!defined($result)||!$result){return;}
}
if($target&&(vec($eout,fileno($target),1)||vec($rout,fileno($target),1))){
my$result=sysread($target,$cbuffer,1024);
if(!defined($result)||!$result){return;}
}
if($fh&&$tbuffer){print$fh$tbuffer;}
while(my$len=length($tbuffer)){
my$res=syswrite($target,$tbuffer,$len);
if($res>0){$tbuffer=substr($tbuffer,$res);}else{return;}
}
while(my$len=length($cbuffer)){
my$res=syswrite($client,$cbuffer,$len);
if($res>0){$cbuffer=substr($cbuffer,$res);}else{return;}
}
}
}
subsocks_bind{
my($client,$host,$port)=@_;
}
subsocks_udp_associate{
my($client,$host,$port)=@_;
}