Delphi 将 SSL tcp 数据重定向到其他端口 no ssl
Delphi Redirect SSL tcp data to other port no ssl
我正在使用 D5(这是事实)。我安装了 Indy9。
我正在尝试在端口 8041 (SSL) 上接收 IdMappedPortTCP
的数据,并将数据重定向到端口 8040 上的 Tserversocket
。所以我将通过 Tserversocket
.[= 支持 SSL 15=]
我使用以下代码:
var
masterdir:String;
begin
masterdir:=Extractfilepath(paramstr(0));
IdMappedPortTCP1.Active:=false;
datamodule2.IdMappedPortTCP1.MappedHost:='192.168.0.3';
datamodule2.IdMappedPortTCP1.MappedPort:=8041;
datamodule2.IdMappedPortTCP1.DefaultPort:=8040;
IdServerIOHandlerSSL1.SSLOptions.RootCertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.CertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.KeyFile:=masterdir+'key.pem';
IdMappedPortTCP1.IOHandler:=IdServerIOHandlerSSL1;
IdMappedPortTCP1.Active:=true;
end;
如果我不使用 SSL,一切都很好。但是当我使用 SSL 时,请求永远不会到达加密的端口 8040,我需要它不加密,所以我可以处理它。
从您的描述中不清楚 TServerSocket
是否在端口 8040 上使用 SSL。它对您设置 TIdMappedPortTCP
的方式有很大影响。但是,根据您的描述,您至少有 MappedPort
和 DefaultPort
属性 分配。 DefaultPort
是TIdMappedPortTCP
监听的端口,所以应该是8041。MappedPort
是TIdMappedPortTCP
连接的端口,所以应该是8040。
在同一个端口上同时存在未加密和加密连接的情况并不常见。大多数协议使用单独的端口。这里是这样吗? 8040端口是否未加密,8041端口是否加密?
如果您希望 TIdMappedPortTCP
在不同的端口上接受加密和未加密的客户端,您需要向 TIdMappedPortTCP.Bindings
集合添加 2 个条目,每个端口一个,而不是使用 DefaultPort
属性 完全没有。在TIdMappedPortTCP.OnConnect
事件中,可以检测客户端连接到哪个端口,然后在AThread.OutboundClient
连接到TServerSocket
.
之前进行相应的配置
将未加密和加密的客户端连接到同一个端口是不明智的。在这种情况下,您必须嗅探前几个字节以了解客户端是否正在发送 SSL 握手,然后采取相应行动。只使用单独的端口更容易。但是,某些协议确实允许客户端连接到未加密的端口,然后在需要时发送命令以激活加密。在这种情况下,您只需要 TIdMappedPortTCP
中的 1 个端口,因此您可以定义 1 Binding
或使用 DefaultPort
.
TIdMappedPortTCP
主要用于在客户端和目标服务器之间来回直接传递原始字节。如果 TServerSocket
使用 SSL 并且您希望客户端 正确地 使用 SSL 与 TServerSocket
通信,您根本不应该使用 TIdServerIOHandlerSSL
。让 TIdMappedPortTCP
将客户端的原始加密数据按原样传递给 TServerSocket
,反之亦然。他们应该彼此建立安全会话,而不是与您建立安全会话。如果其中任何一个执行对等身份验证,这一点尤其重要。
如果您需要处理在客户端和 TServerSocket
之间交换的加密数据,您必须在数据通过 TIdMappedPortTCP
时解密并重新加密(这意味着您是充当中间人攻击者,同行验证旨在防止)。为此,您必须在客户端和 TIdMappedPortTCP
之间以及 TIdMappedPortTCP
和 TServerSocket
之间建立单独的 SSL 会话。将 TIdServerIOHandlerSSL
分配给 TIdMappedPortTCP
只会促进与客户的会话。您必须手动设置与 TServerSocket
的会话。为此,您必须手动将新的 TIdSSLIOHandlerSocket
对象分配给 OnConnect
事件中的 AThread.OutboundClient.IOHandler
属性。 TIdMappedPortTCP
不会为您处理。
但是,如果 TServerSocket
没有使用 SSL,而您使用 TIdMappedPortTCP
作为通向 TServerSocket
的 SSL 网关,那么您可以跳过 OutboundClient.IOHandler
分配,因为您只需要 1 个 SSL 会话,在 TIdMappedPortTCP
和客户端之间。
现在,话虽如此,Indy 9 中存在一些问题。TIdSSLIOHandlerOpenSSL.PassThrough
属性 默认为 False(因此假设加密最初处于活动状态),并且 TIdServerIOHandlerSSL
假设每个 接受的客户端连接都在使用 SSL,即使它确实不是。如果 未加密 客户端连接到 TIdMappedPortTCP
并分配了 TIdServerIOHandlerSSL
,则客户端将无法正确处理。这些问题已在 Indy 10 中修复。但在 Indy 9 中,您将无法在同一个 TIdMappedPortTCP
组件中处理加密和未加密的客户端。但是,如果您只处理加密客户端,则不会 运行 成为问题。否则,创建 2 TIdMappedPortTCP
个组件,一个侦听未加密的端口,另一个侦听加密的端口。他们可以共享相同的事件处理程序。如果需要,您可以使用 AThread.Connection.Socket.Binding.Port
属性 来了解客户端连接到哪个端口。
我正在使用 D5(这是事实)。我安装了 Indy9。
我正在尝试在端口 8041 (SSL) 上接收 IdMappedPortTCP
的数据,并将数据重定向到端口 8040 上的 Tserversocket
。所以我将通过 Tserversocket
.[= 支持 SSL 15=]
我使用以下代码:
var
masterdir:String;
begin
masterdir:=Extractfilepath(paramstr(0));
IdMappedPortTCP1.Active:=false;
datamodule2.IdMappedPortTCP1.MappedHost:='192.168.0.3';
datamodule2.IdMappedPortTCP1.MappedPort:=8041;
datamodule2.IdMappedPortTCP1.DefaultPort:=8040;
IdServerIOHandlerSSL1.SSLOptions.RootCertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.CertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.KeyFile:=masterdir+'key.pem';
IdMappedPortTCP1.IOHandler:=IdServerIOHandlerSSL1;
IdMappedPortTCP1.Active:=true;
end;
如果我不使用 SSL,一切都很好。但是当我使用 SSL 时,请求永远不会到达加密的端口 8040,我需要它不加密,所以我可以处理它。
从您的描述中不清楚 TServerSocket
是否在端口 8040 上使用 SSL。它对您设置 TIdMappedPortTCP
的方式有很大影响。但是,根据您的描述,您至少有 MappedPort
和 DefaultPort
属性 分配。 DefaultPort
是TIdMappedPortTCP
监听的端口,所以应该是8041。MappedPort
是TIdMappedPortTCP
连接的端口,所以应该是8040。
在同一个端口上同时存在未加密和加密连接的情况并不常见。大多数协议使用单独的端口。这里是这样吗? 8040端口是否未加密,8041端口是否加密?
如果您希望 TIdMappedPortTCP
在不同的端口上接受加密和未加密的客户端,您需要向 TIdMappedPortTCP.Bindings
集合添加 2 个条目,每个端口一个,而不是使用 DefaultPort
属性 完全没有。在TIdMappedPortTCP.OnConnect
事件中,可以检测客户端连接到哪个端口,然后在AThread.OutboundClient
连接到TServerSocket
.
将未加密和加密的客户端连接到同一个端口是不明智的。在这种情况下,您必须嗅探前几个字节以了解客户端是否正在发送 SSL 握手,然后采取相应行动。只使用单独的端口更容易。但是,某些协议确实允许客户端连接到未加密的端口,然后在需要时发送命令以激活加密。在这种情况下,您只需要 TIdMappedPortTCP
中的 1 个端口,因此您可以定义 1 Binding
或使用 DefaultPort
.
TIdMappedPortTCP
主要用于在客户端和目标服务器之间来回直接传递原始字节。如果 TServerSocket
使用 SSL 并且您希望客户端 正确地 使用 SSL 与 TServerSocket
通信,您根本不应该使用 TIdServerIOHandlerSSL
。让 TIdMappedPortTCP
将客户端的原始加密数据按原样传递给 TServerSocket
,反之亦然。他们应该彼此建立安全会话,而不是与您建立安全会话。如果其中任何一个执行对等身份验证,这一点尤其重要。
如果您需要处理在客户端和 TServerSocket
之间交换的加密数据,您必须在数据通过 TIdMappedPortTCP
时解密并重新加密(这意味着您是充当中间人攻击者,同行验证旨在防止)。为此,您必须在客户端和 TIdMappedPortTCP
之间以及 TIdMappedPortTCP
和 TServerSocket
之间建立单独的 SSL 会话。将 TIdServerIOHandlerSSL
分配给 TIdMappedPortTCP
只会促进与客户的会话。您必须手动设置与 TServerSocket
的会话。为此,您必须手动将新的 TIdSSLIOHandlerSocket
对象分配给 OnConnect
事件中的 AThread.OutboundClient.IOHandler
属性。 TIdMappedPortTCP
不会为您处理。
但是,如果 TServerSocket
没有使用 SSL,而您使用 TIdMappedPortTCP
作为通向 TServerSocket
的 SSL 网关,那么您可以跳过 OutboundClient.IOHandler
分配,因为您只需要 1 个 SSL 会话,在 TIdMappedPortTCP
和客户端之间。
现在,话虽如此,Indy 9 中存在一些问题。TIdSSLIOHandlerOpenSSL.PassThrough
属性 默认为 False(因此假设加密最初处于活动状态),并且 TIdServerIOHandlerSSL
假设每个 接受的客户端连接都在使用 SSL,即使它确实不是。如果 未加密 客户端连接到 TIdMappedPortTCP
并分配了 TIdServerIOHandlerSSL
,则客户端将无法正确处理。这些问题已在 Indy 10 中修复。但在 Indy 9 中,您将无法在同一个 TIdMappedPortTCP
组件中处理加密和未加密的客户端。但是,如果您只处理加密客户端,则不会 运行 成为问题。否则,创建 2 TIdMappedPortTCP
个组件,一个侦听未加密的端口,另一个侦听加密的端口。他们可以共享相同的事件处理程序。如果需要,您可以使用 AThread.Connection.Socket.Binding.Port
属性 来了解客户端连接到哪个端口。