2012-09-25 3 views
1

안녕하세요! 필자는 Perl을 잘 쓰지는 않지만 끔찍한 필요가있다. 나는 잘 작동Perl tcp_proxy for http

#!/usr/bin/perl 

use warnings; 
use strict; 

use IO::Socket::INET; 
use IO::Select; 

my @allowed_ips = ('all'); 
my $ioset = IO::Select->new; 
my %socket_map; 

my $debug = 1; 

sub new_conn { 

    my ($host, $port) = @_; 
    return IO::Socket::INET->new(
     PeerAddr => $host, 
     PeerPort => $port 
    ) || die "Unable to connect to $host:$port: $!"; 
} 

sub new_server { 
    my ($host, $port) = @_; 

    my $server = IO::Socket::INET->new(
     LocalAddr => $host, 
     LocalPort => $port, 
     ReuseAddr => 1, 
     Listen => 100 
    ) || die "Unable to listen on $host:$port: $!"; 
} 

sub new_connection { 
    my $server  = shift; 
    my $remote_host = shift; 
    my $remote_port = shift; 

    my $client = $server->accept; 
    my $client_ip = client_ip($client); 

    unless (client_allowed($client)) { 

     print "Connection from $client_ip denied.\n" if $debug; 
     $client->close; 
     return; 
    } 
    print "Connection from $client_ip accepted.\n" if $debug; 

    my $remote = new_conn($remote_host, $remote_port); 
    $ioset->add($client); 
    $ioset->add($remote); 

    $socket_map{$client} = $remote; 
    $socket_map{$remote} = $client; 
} 

sub close_connection { 
    my $client = shift; 

    my $client_ip = client_ip($client); 
    my $remote = $socket_map{$client}; 

    $ioset->remove($client); 
    $ioset->remove($remote); 

    delete $socket_map{$client}; 
    delete $socket_map{$remote}; 

    $client->close; 
    $remote->close; 

    print "Connection from $client_ip closed.\n" if $debug; 
} 

sub client_ip { 
    my $client = shift; 

    return inet_ntoa($client->sockaddr); 
} 

sub client_allowed { 
    my $client = shift; 

    my $client_ip = client_ip($client); 
    return grep { $_ eq $client_ip || $_ eq 'all' } @allowed_ips; 
} 

die "Usage: $0 <local port> <remote_host:remote_port>" unless @ARGV == 2; 

my $local_port = shift; 
my ($remote_host, $remote_port) = split ':', shift(); 


print "Starting a server on 0.0.0.0:$local_port\n"; 
my $server = new_server('0.0.0.0', $local_port); 
$ioset->add($server); 

while (1) { 

    for my $socket ($ioset->can_read) { 

     if ($socket == $server) { 

      new_connection($server, $remote_host, $remote_port); 
     } 
     else { 

      next unless exists $socket_map{$socket}; 
      my $remote = $socket_map{$socket}; 
      my $buffer; 
      my $read = $socket->sysread($buffer, 4096); 

      if ($read) { 

       $remote->syswrite($buffer); 
      } 
      else { 

       close_connection($socket); 
      } 
     } 
    } 
} 

모두가 리버스 프록시로 조직을위한 완벽한 솔루션을 ... 찾았지만, 웹 서버는 내가 클라이언트가 HTTP_X_FORWARDED_FOR 및 HTTP_X_REAL_IP 보지 않는다 리디렉션. 표준 모듈이 낮을수록 좋습니다. 귀하의 도움에 감사드립니다.

답변

1

표시되지 않습니다. HTTP 리디렉션이 아닌 TCP 리다이렉션을 만들기 때문에 프록시는 새로운 헤더를 추가하지 않습니다. 이 필드를 가져 오려면 HTTP 수준에서 리디렉션을해야합니다.

+0

링크를 알고 계셨습니까? – user1697198

관련 문제