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)=@_; }