使用libssl和sendmsg()SCM_RIGHTS实现SSL服务器

时间:2012-02-21 15:44:41

标签: linux openssl nph

我现在想知道我们是否可以在Linux环境下根据以下策略/方案制作某种SSL服务器。

(1)对于初始请求,它应该在父服务器进程中传入。在建立SSL连接并处理请求的初始解析之后,请求(套接字)将被转发到请求处理过程以进行进一步处理。

(2)请求处理过程将是应该事先运行的事情。在这个意义上,我们不会使用任何基于fork-exec-pipe的方案。

(3)对于父服务器进程和请求处理进程之间的通信,已经建立了一些IPC,以便通过使用sendmsg()将打开的套接字描述符从父服务器进程复制到请求处理进程 - SCM_RIGHTS技术。

(4)在SSL功能方面,我们应该使用OpenSSL(libssl)。

(5)在请求处理过程中,我们应该通过使用来自父服务器进程的共享套接字描述符来创建新的SSL套接字。

关键是我不想浪费任何在服务器和请求处理过程之间传输数据的性能。我也不想根据请求生成请求处理过程。所以我想提前产生请求处理过程。

虽然我不确定我在这里尝试做的是否对你有意义,但如果你们中的任何人能够给我一些关于上述方法是否可行的暗示,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

目前尚不清楚您究竟在寻找什么,尤其是您想要进行SSL加密/解密的地方。

您是否想在请求处理程序进程中进行加密/解密?
这似乎更可能是解释。但是,您谈到在主进程中进行一些请求解析。在主进程中解析的数据是否已成为SSL会话的一部分?如果是这样,您必须在主进程中进行SSL握手(初始化和密钥交换)才能访问加密数据。如果您随后将原始套接字传递给另一个进程,则它将无法访问父进程的SSL状态,因此无法继续解密父进程所在的位置。如果它尝试在套接字上重新初始化SSL,就好像它是一个干净的连接,客户端可能(正确地)在连接过程中将未经请求的握手视为协议错误并终止连接。如果没有,它会出现安全漏洞,因为它可能是恶意重定向客户端网络流量的攻击者,而不是强制重新初始化的请求处理进程。通常不可能将初始化的SSL会话传递给不同的进程而不通知它们OpenSSL的完整内部状态(交换密钥,一些序列号等)以及这一点,如果不是不可能的话,这将很难。

如果您不需要在父进程中触摸SSL会话,并且只解析在实际SSL会话启动之前出现的一些未加密数据(类似于IMAP中的STARTTLS命令),那么您的想法将毫无问题地工作。只需阅读您需要的内容,直到SSL交换应该开始的位置,然后使用SCM_RIGHTS将套接字传递到后端进程(参见例如cmsg(3)this site中的示例)。还有一些库可以帮助您完成工作,即libancillary

或者您希望主进程为请求处理程序进程执行SSL加密/解密吗?
在这种情况下,将原始套接字传递给请求处理程序进程是没有意义的,因为他们从中获取的唯一内容是加密数据。在该场景中,您必须打开与后端进程的新连接,因为它将携带不同的数据(已解密)。然后,主进程将从网络套接字读取加密数据,对其进行解密并将结果写入请求处理程序的新套接字。类似地在另一个方向。

注意:如果您只是希望您的请求处理流程根本不用担心SSL,我建议让他们监听环回接口并使用stud之类的东西来执行SSL / TLS脏工作

简而言之,您必须选择上述之一。不可能同时做两件事。