+ -
当前位置:首页 → 问答吧 → 用perl的POE模块实现端口重定向。

用perl的POE模块实现端口重定向。

时间:2010-10-15

来源:互联网

本帖最后由 疑似精神病 于 2010-10-15 10:11 编辑

我的提问帖在这里: http://bbs.chinaunix.net/thread-1799692-1-1.html

目的:
两台机器A和B。B上运行着驻守n端口的某个服务。在A机器用perl实现一个驻守m端口的脚本程序。

别的用户通过连接A机器的m端口时,A上的perl脚本程序提供服务,然后再去连接B上的n端口。用户输入的命令,perl脚本程序就再传给B的n端口,并且将B的反馈传回给用户。(单纯只是端口转发用iptables就能实现)
但是当用户输入某些特殊的命令时,perl脚本程序就把用户的命令修改,然后在发给B。

比方客户输入haha,perl脚本程序直接把haha传给B机器。
但是用户输入heihei的时候,perl脚本程序就修改成xixi,传给B机器。

perl脚本程序就相当于一个代理角色。

我需要的是一个pop3代理,过滤用户输入的邮件地址,并且去掉@后面的域,例如用户输入:[email protected] ,perl程序提取test,传给B程序。

安装POE模块:
#wget http://mirrors.163.com/cpan/modu ... TO/POE-1.293.tar.gz
#tar zxvf POE-1.293.tar.gz
#cd POE-1.293/lib
#perl -v
然后复制到对应版本目录。
#cp -a * /usr/lib/perl5/5.8.x/

perl代码:
  1. #!/usr/bin/perl
  2. ##
  3. ## portproxy perl script.
  4. ## http://poe.perl.org/?POE_Cookbook/TCP_Port_Redirection_With_Components
  5. ## modified by dogking email:[email protected] version:0.5 update:2010-10-14
  6. ##

  7. use strict;
  8. use POE qw(Component::Server::TCP Component::Client::TCP);

  9. $main::LocalPort = '8110';
  10. $main::RemoteHost = 'mail.example.com';
  11. $main::RemotePort = '110';

  12. POE::Component::Server::TCP->new(
  13.   Port            => $main::LocalPort,
  14.   ClientConnected => sub {
  15.     my ($heap, $session) = @_[HEAP, SESSION];
  16.     spawn_client_side();
  17.   },
  18.   ClientInput => sub {
  19.     my ($kernel, $session, $heap, $input) = @_[KERNEL, SESSION, HEAP, ARG0];
  20.     #print "$input\n";
  21.     my @myuser = split(/@/,$input);
  22.     $input = $myuser[0];
  23.     #print "$input\n";
  24.     $kernel->post($heap->{client_id} => send_stuff => $input);
  25.   },
  26.   ClientDisconnected => sub {
  27.     my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
  28.     $kernel->post($heap->{client_id} => "shutdown");
  29.   },
  30.   InlineStates => {
  31.     send_stuff => sub {
  32.       my ($heap, $stuff) = @_[HEAP, ARG0];
  33.       $heap->{client}->put($stuff);
  34.     },
  35.     _child => sub {
  36.       my ($heap, $child_op, $child) = @_[HEAP, ARG0, ARG1];
  37.       if ($child_op eq "create") {
  38.         $heap->{client_id} = $child->ID;
  39.       }
  40.     },
  41.   },
  42. );

  43. sub spawn_client_side {
  44.   POE::Component::Client::TCP->new(
  45.     RemoteAddress => $main::RemoteHost,
  46.     RemotePort    => $main::RemotePort,
  47.     Started       => sub {
  48.       $_[HEAP]->{server_id} = $_[SENDER]->ID;
  49.     },
  50.     Connected => sub {
  51.       my ($heap, $session) = @_[HEAP, SESSION];
  52.     },
  53.     ServerInput => sub {
  54.       my ($kernel, $heap, $session, $input) = @_[KERNEL, HEAP, SESSION, ARG0];
  55.       #print "$input\n";
  56.       $kernel->post($heap->{server_id} => send_stuff => $input);
  57.     },
  58.     Disconnected => sub {
  59.       my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
  60.       $kernel->post($heap->{server_id} => 'shutdown');
  61.     },
  62.     InlineStates => {
  63.       send_stuff => sub {
  64.         my ($heap, $stuff) = @_[HEAP, ARG0];
  65.         $heap->{server}->put($stuff);
  66.       },
  67.     },
  68.   );
  69. }

  70. $poe_kernel->run();
  71. exit 0;
复制代码
#./portproxy.pl 2> /dev/null &

测试:[root@localhost ~]
# netstat -tnulp | grep 8110
tcp        0      0 0.0.0.0:8110                0.0.0.0:*                   LISTEN      17428/perl   


[root@localhost ~]# telnet 127.0.0.1 8110
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
+OK Hello there.
user [email protected] #这里实际传给对方pop3的是linux,perl程序自动去掉了@example.com。
+OK Password required.
pass yourpassword
+OK logged in.
list
+OK POP3 clients that break here, they violate STD53.
1 5636
2 13042
3 6942
4 704
5 4325
.
quit
+OK Bye-bye.
Connection closed by foreign host.


这个程序还能驻守其他端口和服务,关于命令的修改还能加上更加丰富的功能。

作者: 疑似精神病   发布时间: 2010-10-15

感谢原创和分享。
btw, pop3代理用nginx+自定义filter也可以完成这个工作。

作者: 兰花仙子   发布时间: 2010-10-15



QUOTE:
感谢原创和分享。
btw, pop3代理用nginx+自定义filter也可以完成这个工作。
兰花仙子 发表于 2010-10-15 09:42




    仙子~
机器上没有nginx环境,考虑到perl基本每个linux都带了,就想用perl试试。perl真是太牛叉了,基本啥刁钻问题都能搞定,就想瑞士军刀一样。

作者: 疑似精神病   发布时间: 2010-10-15

支持

作者: toniz   发布时间: 2010-10-15



QUOTE:
然后复制到对应版本目录。
#cp -a * /usr/lib/perl5/5.8.x/


Perl 安装模块不是这么安装的。

perl Makefile.PL
make
make test
make install

作者: flw   发布时间: 2010-10-15

回复 flw


    有时候安装模块,make经常报错,该怎么解决呢?

作者: yybmsrs   发布时间: 2010-10-15