You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让HTTPS服务器进程池配合安全SSL连接工作?

进程池架构下HTTPS服务器的实现困境

我已实现一款HTTP服务器,采用主进程接受连接、预生成进程池处理请求的架构,通过sendmsg()结合msghdr与cmsghdr传递已打开的套接字。
同时,我也通过<openssl/ssl.h>中的SSL_CTX_new、SSL_new、SSL_accept、SSL_read等函数,完成了单进程HTTPS服务器的常规实现。

但我始终无法将两者结合,核心需求与困境如下:

  • 拒绝为每个请求新建进程,必须使用预生成的进程池
  • 主进程需以root权限运行以访问私钥,但进程池绝不允许以root身份运行
  • 主进程必须完成SSL_new创建SSL*并执行SSL_accept()握手,但找不到方法将SSL*与套接字一同传递给进程池(已知Apache实现了该逻辑)

开发环境为FreeBSD,使用C/C++语言,无法更换开发语言。

以下是已实现的关键代码大纲:

非安全服务器主进程代码

union cmsghdr_with_int
{ struct cmsghdr hdr;
  unsigned char buffer[CMSG_SPACE(sizeof(int))]; };

main()
----
   listensock = socket(AF_INET, SOCK_STREAM, 0);
   setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, (char *) & r, sizeof(r));
   struct sockaddr_in addr; ...... fill it up ......
   bind(listensock, (struct sockaddr *) & addr, sizeof(addr));
   listen(listensock, 5);
   socketpair(PF_LOCAL, SOCK_STREAM, 0, sockpair);
   for each child
     pid_t p = fork();
     if (p == 0)
       close(sockpair[0]);
       child_run();
   close(sockpair[1]);
   loop:
      ... select(listensock + 1, & fds, NULL, NULL, & tv);
      acceptsock = accept(listensock, NULL, NULL);
      ... set up cmsghdr_with_int msgctrlbuffer
      ... and msghdr msghd with iov length 1
      ... and char socketbuffer[...] 
      ... and struct cmsghdr * msgctrl with SOL_SOCKET, SCM_RIGHTS, CMSG_LEN
      * (int *) CMSG_DATA(msgctrl) = acceptsock;
      sendmsg(sockpair[0], & msghd, 0);
      r = close(acceptsock);
   close(listensock);

非安全服务器进程池代码

main()
----
   loop:
      ... set up msghdr msghd with iovlen 1, CMSG_SPACE
      recvmsg(fromserver, & msghd, 0);
      msgctrl = CMSG_FIRSTHDR(& msghd);
      while (msgctrl != NULL)
         if ... CMSG_LEN, SOL_SOCKET, SCM_RIGHTS ...
            acceptsock = * (int *) CMSG_DATA(msgctrl);
            read headers
            send response
            close acceptsock

单进程安全服务器代码

main()
----

  const SSL_METHOD * meth = TLS_server_method();
  sslctxt = SSL_CTX_new(meth);
  SSL_CTX_use_certificate_file(sslctxt, "...apache...xxxxx.crt", SSL_FILETYPE_PEM);
  SSL_CTX_use_PrivateKey_file(sslctxt, "...apache...xxxxx.key", SSL_FILETYPE_PEM);
  ... the usual socket-bind-listen

  while (... still serving ...)
    int sock = accept(mainsock, ... usual
    SSL * sslio = SSL_new(sslctxt);
    SSL_set_fd(sslio, sock);
    SSL_accept(sslio);
    read headers:
      SSL_read(sslio, buffer, sizeof(buffer) - 1);
    send response:
      SSL_write(sslio, s.c_str(), s.length());
    SSL_shutdown(sslio);
    SSL_free(sslio);
    close(sock);
  close(mainsock);
  SSL_CTX_free(sslctxt);

内容的提问来源于stack exchange,提问作者Jim Sykes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:43:14