编程让你映射1521端口,在外网连接Oracle,从此支持SOHO

    技术2022-05-11  151

    (如果你用oracle.odac并有什么VPN之类的话,其实就无需此文了)(转帖,请注明原创作者: 成都.廖长科 谢谢)

    说明:  此文仅作技术讨论、学习为目的,请自行遵守相关法律,本文作者不承担责任后果.

    环境:       局域网内网地址192.168.2.18上安装了oracle9,TNS端口1521,路由器虚拟服务转发1521端到此地址。想到这样的话,就可以SOHO了.

    状态:  (如果你知道oracle的1521端实际作用可跳过)       外网安了oracle客户端和odac,odac使用net方式,连接成功,并可取出数据。但是ora客户端连管理器的连接测试都通不过,发现连接测试时所连接的地址并非外网地址,变成了192.168.2.18(端口不是1521).        在内网中用PLSQLDeveloper连接后,发现登陆后的实际操作并非是连接1521端口,且有时会变换新端口

    试手开始:       准备了Indy的MappedTCP环境, 过程如下:       1.client发送请求数据, 中间包含了"(HOST=xxxxx.xxxx.xxx)(PORT=4414)",其中HOST为ora连接管理器中配置的主机名,端口同样. 另外后面还有一个HOSP=当前机器的机器名       2.ora每次的命令封包, 头两个字节为Word(16位), 代表此次封包的总长度(注意也包含了Word自身), 第五个字节在第一次连接时为byte(1), 此后知道应该是命令号, 命令号的长度不清楚, sorry。命令号后的字节不清楚用途,但有时候是记录此次封包内下一段的字节长度(同样包含长度Word自身).       3.服务端收到后,1521端返回了命令号为byte(5)的命令,数据的确包含了新分配给客户端连接的端口和IP,OK了,改数据       修改思想

           1.在TIdMappedTCP基础上继承, 假设出口地址为4444, Mapped地址当然为192.168.2.18:1521,        2.Client发命令byte(1)时,保存客户端请求的地址,等会儿要返回给客户端的.       3.Server返命令byte(5)时"(HOST=192.168.2.18)(PORT=1031)",把HOST换为刚才保存的地址(也就是说叫客户端再连此IP的程序), 端口1031怎么办喃?  当然是保存起来,由Mapped程序连接, 客户端又连哪儿? 这样: 再内置个MappedTCP服务,Mapped到5号命令返回的Port, 出口地址嘛正好设个4447端.  所以还得把封包中PORT换为4447.              贴个修改包长度的代码:      //changedPackage为已经换了HOST和PORT的string      //注意了哈!!! ora封包大小虽为word, 但与delphi中的word相比,       //其高位和低位正好是相反的, 得转换一下      //      type        psWord = ^tsWord;        tsWord = packed record           b1 : byte;           b2 : byte;        end;       var        ppp : PChar;      begin        wSize := Length(changedPackage);        ppp := @LParm[1];                //反转delphi的word        psWord(@wSize2).b2 := psWord(@wSize).b1;        psWord(@wSize2).b1 := psWord(@wSize).b2;        //写新的大小        Move(wSize2, ppp^, 2);                 //5号命令中子长度, 正好是第8位开始        Inc(ppp, 8);        //读旧的大小再-10        move(ppp^, wSize2, 2);        //写新的子长度, -10是把总长度占的两个字节算进去了的        wSize := wSize-10;        psWord(@wSize2).b2 := psWord(@wSize).b1;        psWord(@wSize2).b1 := psWord(@wSize).b2;        Move(wSize2, ppp^, 2);                4.最后,被保存的1031端口怎么办?          可以把端口地址放到一个队列中,当客户端连接到4447端口,POP出一个端口和缓存的HOST, 作内置IdMappedTCP的MappedHost和MappedPort,  可以将BackMapped.OnConnect := BackConnect, 并在BackConnect中POP出缓存的Port, 因为:

           procedure TIdMappedPortThread.OutboundConnect;       Begin         FOutboundClient := TIdTCPClient.Create(NIL);         with TIdMappedPortTCP(Connection.Server) do begin         try            with TIdTcpClient(FOutboundClient) do begin              Port := MappedPort;              Host := MappedHost;            end;//with            DoLocalClientConnect(SELF); //这里执行OnConnect事件, 下面就会Connect了哈

                TIdTcpClient(FOutboundClient).Connect(FConnectTimeOut);            DoOutboundClientConnect(SELF);         except          on E: Exception do begin            DoOutboundClientConnect(SELF,E);            Connection.Disconnect;           end;         end;//trye         end;//with       End;

    巧功告成:     此程序可以放到可以访问192.168.2.18地址的任意机器上, 程序只监听4444和4447两个端口, 因此,你可以到路由器中设置转发4444/4447两个端口(4444相当于1521端口, 1521端口本身只是作监听端口转发,不作登陆/SQL数据传送滴), 从此便可以远程外网连接ORA了,爽吧,加好密,小心被攻击。

         多看看Indy的TIdMappedFTP对你有帮助, 此思想等于是用4447这个不变应了ora的万变端口. 但ORA有加密封包的功能, 加密后, 就得想办法解密了哈,我想还是可行滴!

    了解更多 QQ:7896615


    最新回复(0)